Provisioning: Add Connection resource (#115272)
* Provisioning: Add Connection resource * adding some more integration tests * updating openapi snapshot, linting * generating FE code, fixing issue in unit tests * addressing comments * addressing comments * adding more integration tests * fixing rebase issues * removing linting exception * addressing comments: improving validation and tests * adding Connection URL at mutation time, updating tests accordingly * linting
This commit is contained in:
@@ -39,6 +39,10 @@ func (m mockProvisioningV0alpha1Interface) Jobs(namespace string) client.JobInte
|
||||
panic("not needed for testing")
|
||||
}
|
||||
|
||||
func (m mockProvisioningV0alpha1Interface) Connections(namespace string) client.ConnectionInterface {
|
||||
panic("not needed for testing")
|
||||
}
|
||||
|
||||
func (m mockProvisioningV0alpha1Interface) Repositories(namespace string) client.RepositoryInterface {
|
||||
if m.repositoriesFunc != nil {
|
||||
return m.repositoriesFunc(namespace)
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
dashboard "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
||||
folders "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1"
|
||||
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
|
||||
connectionvalidation "github.com/grafana/grafana/apps/provisioning/pkg/connection"
|
||||
appcontroller "github.com/grafana/grafana/apps/provisioning/pkg/controller"
|
||||
clientset "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned"
|
||||
client "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1"
|
||||
@@ -354,6 +355,8 @@ func (b *APIBuilder) authorizeResource(ctx context.Context, a authorizer.Attribu
|
||||
return b.authorizeSettings(id)
|
||||
case provisioning.JobResourceInfo.GetName(), provisioning.HistoricJobResourceInfo.GetName():
|
||||
return b.authorizeJobs(id)
|
||||
case provisioning.ConnectionResourceInfo.GetName():
|
||||
return b.authorizeConnectionSubresource(a, id)
|
||||
default:
|
||||
return b.authorizeDefault(id)
|
||||
}
|
||||
@@ -437,6 +440,28 @@ func (b *APIBuilder) authorizeJobs(id identity.Requester) (authorizer.Decision,
|
||||
return authorizer.DecisionDeny, "admin role is required", nil
|
||||
}
|
||||
|
||||
// authorizeRepositorySubresource handles authorization for connections subresources.
|
||||
func (b *APIBuilder) authorizeConnectionSubresource(a authorizer.Attributes, id identity.Requester) (authorizer.Decision, string, error) {
|
||||
switch a.GetSubresource() {
|
||||
case "":
|
||||
// Doing something with the connection itself.
|
||||
if id.GetOrgRole().Includes(identity.RoleAdmin) {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
return authorizer.DecisionDeny, "admin role is required", nil
|
||||
case "status":
|
||||
if id.GetOrgRole().Includes(identity.RoleViewer) && a.GetVerb() == apiutils.VerbGet {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
return authorizer.DecisionDeny, "users cannot update the status of a connection", nil
|
||||
default:
|
||||
if id.GetIsGrafanaAdmin() {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
return authorizer.DecisionDeny, "unmapped subresource defaults to no access", nil
|
||||
}
|
||||
}
|
||||
|
||||
// authorizeDefault handles authorization for unmapped resources.
|
||||
func (b *APIBuilder) authorizeDefault(id identity.Requester) (authorizer.Decision, string, error) {
|
||||
// We haven't bothered with this kind yet.
|
||||
@@ -520,10 +545,19 @@ func (b *APIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupI
|
||||
storage[provisioning.HistoricJobResourceInfo.StoragePath()] = historicJobStore
|
||||
}
|
||||
|
||||
connectionsStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, provisioning.ConnectionResourceInfo, opts.OptsGetter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create connection storage: %w", err)
|
||||
}
|
||||
connectionStatusStorage := grafanaregistry.NewRegistryStatusStore(opts.Scheme, connectionsStore)
|
||||
|
||||
storage[provisioning.JobResourceInfo.StoragePath()] = jobStore
|
||||
storage[provisioning.RepositoryResourceInfo.StoragePath()] = repositoryStorage
|
||||
storage[provisioning.RepositoryResourceInfo.StoragePath("status")] = repositoryStatusStorage
|
||||
|
||||
storage[provisioning.ConnectionResourceInfo.StoragePath()] = connectionsStore
|
||||
storage[provisioning.ConnectionResourceInfo.StoragePath("status")] = connectionStatusStorage
|
||||
|
||||
// TODO: Add some logic so that the connectors can registered themselves and we don't have logic all over the place
|
||||
storage[provisioning.RepositoryResourceInfo.StoragePath("test")] = NewTestConnector(b, repository.NewRepositoryTesterWithExistingChecker(repository.NewSimpleRepositoryTester(b.validator), b.VerifyAgainstExistingRepositories))
|
||||
storage[provisioning.RepositoryResourceInfo.StoragePath("files")] = NewFilesConnector(b, b.parsers, b.clients, b.access)
|
||||
@@ -566,6 +600,11 @@ func (b *APIBuilder) Mutate(ctx context.Context, a admission.Attributes, o admis
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
// TODO: complete this as part of https://github.com/grafana/git-ui-sync-project/issues/700
|
||||
c, ok := obj.(*provisioning.Connection)
|
||||
if ok {
|
||||
return connectionvalidation.MutateConnection(c)
|
||||
}
|
||||
|
||||
r, ok := obj.(*provisioning.Repository)
|
||||
if !ok {
|
||||
@@ -615,6 +654,11 @@ func (b *APIBuilder) Validate(ctx context.Context, a admission.Attributes, o adm
|
||||
return nil
|
||||
}
|
||||
|
||||
connection, ok := obj.(*provisioning.Connection)
|
||||
if ok {
|
||||
return connectionvalidation.ValidateConnection(connection)
|
||||
}
|
||||
|
||||
// Validate Jobs
|
||||
job, ok := obj.(*provisioning.Job)
|
||||
if ok {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,413 @@
|
||||
package provisioning
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/util/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func TestIntegrationProvisioning_ConnectionCRUDL(t *testing.T) {
|
||||
testutil.SkipIntegrationTestInShortMode(t)
|
||||
|
||||
helper := runGrafana(t)
|
||||
createOptions := metav1.CreateOptions{FieldValidation: "Strict"}
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("should perform CRUDL requests on connection", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "github",
|
||||
"github": map[string]any{
|
||||
"appID": "123456",
|
||||
"installationID": "454545",
|
||||
},
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
// CREATE
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.NoError(t, err, "failed to create resource")
|
||||
|
||||
// READ
|
||||
output, err := helper.Connections.Resource.Get(ctx, "connection", metav1.GetOptions{})
|
||||
require.NoError(t, err, "failed to read back resource")
|
||||
assert.Equal(t, "connection", output.GetName(), "name should be equal")
|
||||
assert.Equal(t, "default", output.GetNamespace(), "namespace should be equal")
|
||||
spec := output.Object["spec"].(map[string]any)
|
||||
assert.Equal(t, "github", spec["type"], "type should be equal")
|
||||
assert.Equal(t, "https://github.com/settings/installations/454545", spec["url"], "url should be equal")
|
||||
require.Contains(t, spec, "github")
|
||||
githubInfo := spec["github"].(map[string]any)
|
||||
assert.Equal(t, "123456", githubInfo["appID"], "appID should be equal")
|
||||
assert.Equal(t, "454545", githubInfo["installationID"], "installationID should be equal")
|
||||
require.Contains(t, output.Object, "secure", "object should contain secure")
|
||||
assert.Contains(t, output.Object["secure"], "privateKey", "secure should contain PrivateKey")
|
||||
|
||||
// LIST
|
||||
list, err := helper.Connections.Resource.List(ctx, metav1.ListOptions{})
|
||||
require.NoError(t, err, "failed to list resource")
|
||||
assert.Equal(t, 1, len(list.Items), "should have one connection")
|
||||
assert.Equal(t, "connection", list.Items[0].GetName(), "name should be equal")
|
||||
|
||||
// UPDATE
|
||||
updatedConnection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "github",
|
||||
"github": map[string]any{
|
||||
"appID": "456789",
|
||||
"installationID": "454545",
|
||||
},
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
res, err := helper.Connections.Resource.Update(ctx, updatedConnection, metav1.UpdateOptions{})
|
||||
require.NoError(t, err, "failed to update resource")
|
||||
spec = res.Object["spec"].(map[string]any)
|
||||
require.Contains(t, spec, "github")
|
||||
githubInfo = spec["github"].(map[string]any)
|
||||
assert.Equal(t, "456789", githubInfo["appID"], "appID should be updated")
|
||||
|
||||
// DELETE
|
||||
require.NoError(t, helper.Connections.Resource.Delete(ctx, "connection", metav1.DeleteOptions{}), "failed to delete resource")
|
||||
list, err = helper.Connections.Resource.List(ctx, metav1.ListOptions{})
|
||||
require.NoError(t, err, "failed to list resources")
|
||||
assert.Equal(t, 0, len(list.Items), "should have no connections")
|
||||
})
|
||||
|
||||
t.Run("viewer can't create or get connection", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "github",
|
||||
"github": map[string]any{
|
||||
"appID": "123456",
|
||||
"installationID": "454545",
|
||||
},
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
result := helper.ViewerREST.Post().
|
||||
Namespace("default").
|
||||
Resource("connections").
|
||||
Body(connection).
|
||||
Do(t.Context())
|
||||
|
||||
require.NotNil(t, result.Error())
|
||||
err := &k8serrors.StatusError{}
|
||||
require.True(t, errors.As(result.Error(), &err))
|
||||
assert.Equal(t, metav1.StatusReasonForbidden, err.Status().Reason)
|
||||
assert.Contains(t, err.Status().Message, "User \"viewer\" cannot create resource \"connections\"")
|
||||
assert.Contains(t, err.Status().Message, "admin role is required")
|
||||
|
||||
result = helper.ViewerREST.Get().
|
||||
Namespace("default").
|
||||
Resource("connections").
|
||||
Name("connection").
|
||||
Do(t.Context())
|
||||
require.NotNil(t, result.Error())
|
||||
err = &k8serrors.StatusError{}
|
||||
require.True(t, errors.As(result.Error(), &err))
|
||||
assert.Equal(t, metav1.StatusReasonForbidden, err.Status().Reason)
|
||||
assert.Contains(t, err.Status().Message, "User \"viewer\" cannot get resource \"connections\"")
|
||||
assert.Contains(t, err.Status().Message, "admin role is required")
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntegrationProvisioning_ConnectionValidation(t *testing.T) {
|
||||
helper := runGrafana(t)
|
||||
createOptions := metav1.CreateOptions{FieldValidation: "Strict"}
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("should fail when type is empty", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "",
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "type must be specified")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is invalid", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "some-invalid-type",
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "spec.type: Unsupported value: \"some-invalid-type\"")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is github but 'github' field is not there", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "github",
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "github info must be specified for GitHub connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is github but private key is not there", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "github",
|
||||
"github": map[string]any{
|
||||
"appID": "123456",
|
||||
"installationID": "454545",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "privateKey must be specified for GitHub connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is github but a client Secret is specified", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "github",
|
||||
"github": map[string]any{
|
||||
"appID": "123456",
|
||||
"installationID": "454545",
|
||||
},
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
"clientSecret": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "clientSecret is forbidden in GitHub connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is bitbucket but 'bitbucket' field is not there", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "bitbucket",
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"clientSecret": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "bitbucket info must be specified in Bitbucket connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is bitbucket but client secret is not there", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "bitbucket",
|
||||
"bitbucket": map[string]any{
|
||||
"clientID": "123456",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "clientSecret must be specified for Bitbucket connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is bitbucket but a private key is specified", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "bitbucket",
|
||||
"bitbucket": map[string]any{
|
||||
"clientID": "123456",
|
||||
},
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
"clientSecret": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "privateKey is forbidden in Bitbucket connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is gitlab but 'gitlab' field is not there", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "gitlab",
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"clientSecret": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "gitlab info must be specified in Gitlab connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is gitlab but client secret is not there", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "gitlab",
|
||||
"gitlab": map[string]any{
|
||||
"clientID": "123456",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "clientSecret must be specified for Gitlab connection")
|
||||
})
|
||||
|
||||
t.Run("should fail when type is gitlab but a private key is specified", func(t *testing.T) {
|
||||
connection := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
||||
"kind": "Connection",
|
||||
"metadata": map[string]any{
|
||||
"name": "connection",
|
||||
"namespace": "default",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"type": "gitlab",
|
||||
"gitlab": map[string]any{
|
||||
"clientID": "123456",
|
||||
},
|
||||
},
|
||||
"secure": map[string]any{
|
||||
"privateKey": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
"clientSecret": map[string]any{
|
||||
"create": "someSecret",
|
||||
},
|
||||
},
|
||||
}}
|
||||
_, err := helper.Connections.Resource.Create(ctx, connection, createOptions)
|
||||
require.Error(t, err, "failed to create resource")
|
||||
assert.Contains(t, err.Error(), "privateKey is forbidden in Gitlab connection")
|
||||
})
|
||||
}
|
||||
@@ -53,6 +53,7 @@ type provisioningTestHelper struct {
|
||||
ProvisioningPath string
|
||||
|
||||
Repositories *apis.K8sResourceClient
|
||||
Connections *apis.K8sResourceClient
|
||||
Jobs *apis.K8sResourceClient
|
||||
Folders *apis.K8sResourceClient
|
||||
DashboardsV0 *apis.K8sResourceClient
|
||||
@@ -703,6 +704,11 @@ func runGrafana(t *testing.T, options ...grafanaOption) *provisioningTestHelper
|
||||
Namespace: "default", // actually org1
|
||||
GVR: provisioning.RepositoryResourceInfo.GroupVersionResource(),
|
||||
})
|
||||
connections := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
Namespace: "default", // actually org1
|
||||
GVR: provisioning.ConnectionResourceInfo.GroupVersionResource(),
|
||||
})
|
||||
jobs := helper.GetResourceClient(apis.ResourceClientArgs{
|
||||
User: helper.Org1.Admin,
|
||||
Namespace: "default", // actually org1
|
||||
@@ -763,6 +769,7 @@ func runGrafana(t *testing.T, options ...grafanaOption) *provisioningTestHelper
|
||||
K8sTestHelper: helper,
|
||||
|
||||
Repositories: repositories,
|
||||
Connections: connections,
|
||||
AdminREST: adminClient,
|
||||
EditorREST: editorClient,
|
||||
ViewerREST: viewerClient,
|
||||
|
||||
Reference in New Issue
Block a user