Browse Source

operator functional and retrieves secrets from gitlab

jabray5 4 years ago
parent
commit
d45469acc7

+ 2 - 0
.gitignore

@@ -18,3 +18,5 @@ deploy/charts/external-secrets/templates/crds/*.yaml
 site/
 e2e/k8s/deploy
 e2e/e2e.test
+samples-gitlab/
+samples-GCP/

+ 3 - 3
apis/externalsecrets/v1alpha1/secretstore_gitlab_types.go

@@ -24,8 +24,8 @@ type GitlabProvider struct {
 	// Auth configures how secret-manager authenticates with the IBM secrets manager.
 	Auth GitlabAuth `json:"auth"`
 
-	// ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance
-	ProjectID *string `json:"projectID,omitempty"`
+	// ProjectID project where secret is located
+	ProjectID string `json:"projectID,omitempty"`
 }
 
 type GitlabAuth struct {
@@ -34,5 +34,5 @@ type GitlabAuth struct {
 
 type GitlabSecretRef struct {
 	// The Access Token is used for authentication
-	AccessToken esmeta.SecretKeySelector `json:"token,omitempty"`
+	AccessToken esmeta.SecretKeySelector `json:"accessToken,omitempty"`
 }

+ 1 - 0
apis/externalsecrets/v1alpha1/secretstore_types.go

@@ -57,6 +57,7 @@ type SecretStoreProvider struct {
 	// YandexLockbox configures this store to sync secrets using Yandex Lockbox provider
 	// +optional
 	YandexLockbox *YandexLockboxProvider `json:"yandexlockbox,omitempty"`
+
 	// GItlab configures this store to sync secrets using Gitlab Variables provider
 	// +optional
 	Gitlab *GitlabProvider `json:"gitlab,omitempty"`

+ 51 - 0
apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go

@@ -505,6 +505,54 @@ func (in *GCPSMProvider) DeepCopy() *GCPSMProvider {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GitlabAuth) DeepCopyInto(out *GitlabAuth) {
+	*out = *in
+	in.SecretRef.DeepCopyInto(&out.SecretRef)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabAuth.
+func (in *GitlabAuth) DeepCopy() *GitlabAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(GitlabAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GitlabProvider) DeepCopyInto(out *GitlabProvider) {
+	*out = *in
+	in.Auth.DeepCopyInto(&out.Auth)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabProvider.
+func (in *GitlabProvider) DeepCopy() *GitlabProvider {
+	if in == nil {
+		return nil
+	}
+	out := new(GitlabProvider)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GitlabSecretRef) DeepCopyInto(out *GitlabSecretRef) {
+	*out = *in
+	in.AccessToken.DeepCopyInto(&out.AccessToken)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabSecretRef.
+func (in *GitlabSecretRef) DeepCopy() *GitlabSecretRef {
+	if in == nil {
+		return nil
+	}
+	out := new(GitlabSecretRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *IBMAuth) DeepCopyInto(out *IBMAuth) {
 	*out = *in
 	in.SecretRef.DeepCopyInto(&out.SecretRef)
@@ -647,6 +695,9 @@ func (in *SecretStoreProvider) DeepCopyInto(out *SecretStoreProvider) {
 	if in.YandexLockbox != nil {
 		in, out := &in.YandexLockbox, &out.YandexLockbox
 		*out = new(YandexLockboxProvider)
+	if in.Gitlab != nil {
+		in, out := &in.Gitlab, &out.Gitlab
+		*out = new(GitlabProvider)
 		(*in).DeepCopyInto(*out)
 	}
 }

+ 42 - 0
deploy/crds/external-secrets.io_clustersecretstores.yaml

@@ -250,6 +250,48 @@ spec:
                         description: ProjectID project where secret is located
                         type: string
                     type: object
+                  gitlab:
+                    description: Gitlab configures this store to sync variables using
+                      Gitlab CI
+                    properties:
+                      auth:
+                        description: Auth configures how secret-manager authenticates
+                          with the IBM secrets manager.
+                        properties:
+                          SecretRef:
+                            properties:
+                              accessToken:
+                                description: The Access Token is used for authentication
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                            type: object
+                        required:
+                        - SecretRef
+                        type: object
+                      projectID:
+                        description: ProjectID project where secret is located
+                        type: string
+                    required:
+                    - auth
+                    type: object
                   ibm:
                     description: IBM configures this store to sync secrets using IBM
                       Cloud provider

+ 42 - 0
deploy/crds/external-secrets.io_secretstores.yaml

@@ -250,6 +250,48 @@ spec:
                         description: ProjectID project where secret is located
                         type: string
                     type: object
+                  gitlab:
+                    description: Gitlab configures this store to sync variables using
+                      Gitlab CI
+                    properties:
+                      auth:
+                        description: Auth configures how secret-manager authenticates
+                          with the IBM secrets manager.
+                        properties:
+                          SecretRef:
+                            properties:
+                              accessToken:
+                                description: The Access Token is used for authentication
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                            type: object
+                        required:
+                        - SecretRef
+                        type: object
+                      projectID:
+                        description: ProjectID project where secret is located
+                        type: string
+                    required:
+                    - auth
+                    type: object
                   ibm:
                     description: IBM configures this store to sync secrets using IBM
                       Cloud provider

+ 3 - 1
go.mod

@@ -3,6 +3,7 @@ module github.com/external-secrets/external-secrets
 go 1.16
 
 replace (
+	github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1 => ./apis/externalsecrets/v1alpha1
 	google.golang.org/grpc => google.golang.org/grpc v1.27.0
 
 	k8s.io/api => k8s.io/api v0.21.2
@@ -51,7 +52,6 @@ require (
 	github.com/googleapis/gax-go v1.0.3
 	github.com/hashicorp/go-hclog v0.14.1 // indirect
 	github.com/hashicorp/go-multierror v1.1.1 // indirect
-	github.com/hashicorp/go-retryablehttp v0.6.7 // indirect
 	github.com/hashicorp/hcl v1.0.1-vault // indirect
 	github.com/hashicorp/vault/api v1.0.5-0.20210224012239-b540be4b7ec4
 	github.com/kr/pretty v0.2.1 // indirect
@@ -66,6 +66,7 @@ require (
 	github.com/tidwall/gjson v1.7.5
 	github.com/yandex-cloud/go-genproto v0.0.0-20210809082946-a97da516c588
 	github.com/yandex-cloud/go-sdk v0.0.0-20210809100642-c13c40a429fa
+	github.com/xanzy/go-gitlab v0.50.1
 	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a
 	go.uber.org/zap v1.17.0
 	golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
@@ -73,6 +74,7 @@ require (
 	golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c
 	golang.org/x/tools v0.1.2-0.20210512205948-8287d5da45e4 // indirect
 	google.golang.org/api v0.30.0
+	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a
 	google.golang.org/grpc v1.31.0
 	honnef.co/go/tools v0.1.4 // indirect

+ 8 - 2
go.sum

@@ -294,6 +294,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
@@ -355,8 +357,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9
 github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
 github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
 github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
-github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo=
-github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
+github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
+github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
 github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
 github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
 github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
@@ -644,6 +646,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/xanzy/go-gitlab v0.50.1 h1:eH1G0/ZV1j81rhGrtbcePjbM5Ern7mPA4Xjt+yE+2PQ=
+github.com/xanzy/go-gitlab v0.50.1/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE=
 github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
 github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
@@ -790,6 +794,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -978,6 +983,7 @@ google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
 google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
 google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
 google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=

+ 101 - 13
pkg/provider/gitlab/gitlab.go

@@ -24,46 +24,123 @@ import (
 
 	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
 	gitlab "github.com/xanzy/go-gitlab"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/types"
+	kclient "sigs.k8s.io/controller-runtime/pkg/client"
+
+	"github.com/external-secrets/external-secrets/pkg/provider"
+	"github.com/external-secrets/external-secrets/pkg/provider/schema"
 )
 
 // Requires a token to be set in environment variable
 var GITLAB_TOKEN = os.Getenv("GITLAB_TOKEN")
 var GITLAB_PROJECT_ID = os.Getenv("GITLAB_PROJECT_ID")
 
+const (
+	// TODO: Make these more descriptive
+	errGitlabCredSecretName                   = "error with credentials"
+	errInvalidClusterStoreMissingSAKNamespace = "error"
+	errFetchSAKSecret                         = "couldn't find secret on cluster: %w"
+	errMissingSAK                             = "error"
+)
+
+// Probably don't need this any more
 type GitlabCredentials struct {
 	Token string `json:"token"`
 }
 
-// Gitlab struct with reference to a github client and a projectID
+// Gitlab Provider struct with reference to a github client and a projectID
 type Gitlab struct {
 	client    *gitlab.Client
 	projectID interface{}
 }
 
+// Client for interacting with kubernetes cluster...?
+type gClient struct {
+	kube        kclient.Client
+	store       *esv1alpha1.GitlabProvider
+	namespace   string
+	storeKind   string
+	credentials []byte
+}
+
+func init() {
+	schema.Register(&Gitlab{}, &esv1alpha1.SecretStoreProvider{
+		Gitlab: &esv1alpha1.GitlabProvider{},
+	})
+}
+
+// Set gClient credentials to Access Token
+func (c *gClient) setAuth(ctx context.Context) error {
+	credentialsSecret := &corev1.Secret{}
+	credentialsSecretName := c.store.Auth.SecretRef.AccessToken.Name
+	if credentialsSecretName == "" {
+		return fmt.Errorf(errGitlabCredSecretName)
+	}
+	objectKey := types.NamespacedName{
+		Name:      credentialsSecretName,
+		Namespace: c.namespace,
+	}
+	// only ClusterStore is allowed to set namespace (and then it's required)
+	if c.storeKind == esv1alpha1.ClusterSecretStoreKind {
+		if c.store.Auth.SecretRef.AccessToken.Namespace == nil {
+			return fmt.Errorf(errInvalidClusterStoreMissingSAKNamespace)
+		}
+		objectKey.Namespace = *c.store.Auth.SecretRef.AccessToken.Namespace
+	}
+
+	err := c.kube.Get(ctx, objectKey, credentialsSecret)
+	if err != nil {
+		return fmt.Errorf(errFetchSAKSecret, err)
+	}
+
+	c.credentials = credentialsSecret.Data[c.store.Auth.SecretRef.AccessToken.Key]
+	if (c.credentials == nil) || (len(c.credentials) == 0) {
+		return fmt.Errorf(errMissingSAK)
+	}
+	c.store.ProjectID = string(credentialsSecret.Data[c.store.ProjectID])
+	return nil
+}
+
 // Function newGitlabProvider returns a reference to a new instance of a 'Gitlab' struct
 func NewGitlabProvider() *Gitlab {
 	return &Gitlab{}
 }
 
-// Method on Gitlab to set up client with credentials and populate projectID
-func (g *Gitlab) NewGitlabClient(cred GitlabCredentials, projectID string) {
+// Method on Gitlab Provider to set up client with credentials and populate projectID
+func (g *Gitlab) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube kclient.Client, namespace string) (provider.SecretsClient, error) {
+	storeSpec := store.GetSpec()
+	if storeSpec == nil || storeSpec.Provider == nil || storeSpec.Provider.Gitlab == nil {
+		return nil, fmt.Errorf("no store type or wrong store type")
+	}
+	storeSpecGitlab := storeSpec.Provider.Gitlab
+
+	cliStore := gClient{
+		kube:      kube,
+		store:     storeSpecGitlab,
+		namespace: namespace,
+		storeKind: store.GetObjectKind().GroupVersionKind().Kind,
+	}
+
+	if err := cliStore.setAuth(ctx); err != nil {
+		return nil, err
+	}
+
 	var err error
 	// Create a new Gitlab client with credentials
-	g.client, err = gitlab.NewClient(cred.Token, nil)
-	g.projectID = projectID
+	gitlabClient, err := gitlab.NewClient(string(cliStore.credentials), nil)
 	if err != nil {
 		log.Fatalf("Failed to create client: %v", err)
 	}
+	g.client = gitlabClient
+	g.projectID = cliStore.store.ProjectID
+
+	return g, nil
+
 }
 
 func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	data, _, err := g.client.ProjectVariables.GetVariable(g.projectID, ref.Key, nil) //Optional 'filter' parameter could be added later
-	// Do we need versions or anything?
-	if err != nil {
-		return nil, err
-	}
-
-	// Returns a secret in the form
+	// Retrieves a gitlab variable in the form
 	// {
 	// 	"key": "TEST_VARIABLE_1",
 	// 	"variable_type": "env_var",
@@ -71,16 +148,23 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
 	// 	"protected": false,
 	// 	"masked": true
 	// }
+	data, _, err := g.client.ProjectVariables.GetVariable(g.projectID, ref.Key, nil) //Optional 'filter' parameter could be added later
+	if err != nil {
+		return nil, err
+	}
 
+	// Return only the variable's 'value'
 	return []byte(data.Value), nil
 }
 
 func (g *Gitlab) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
+	// Gets a secret as normal, expecting secret value to be a json object
 	data, err := g.GetSecret(ctx, ref)
 	if err != nil {
 		return nil, fmt.Errorf("error getting secret %s: %w", ref.Key, err)
 	}
 
+	// Maps the json data to a string:string map
 	kv := make(map[string]string)
 	err = json.Unmarshal(data, &kv)
 	if err != nil {
@@ -88,10 +172,14 @@ func (g *Gitlab) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecret
 		return nil, err
 	}
 
-	// Converts values in K:V pairs into bytes while leaving keys as strings
+	// Converts values in K:V pairs into bytes, while leaving keys as strings
 	secretData := make(map[string][]byte)
 	for k, v := range kv {
 		secretData[k] = []byte(v)
 	}
 	return secretData, nil
 }
+
+func (g *Gitlab) Close() error {
+	return nil
+}

+ 32 - 38
pkg/provider/gitlab/gitlab_test.go

@@ -13,55 +13,49 @@ limitations under the License.
 */
 package gitlab
 
-import (
-	"context"
-	"fmt"
-	"testing"
+// NOT WORKING CURRENTLY
 
-	"github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
-)
+// func TestCreateGitlabClient(t *testing.T) {
+// 	credentials := GitlabCredentials{Token: GITLAB_TOKEN}
+// 	gitlab := NewGitlabProvider()
+// 	gitlab.SetAuth(credentials, GITLAB_PROJECT_ID)
 
-func TestCreateGitlabClient(t *testing.T) {
-	credentials := GitlabCredentials{Token: GITLAB_TOKEN}
-	gitlab := NewGitlabProvider()
-	gitlab.NewGitlabClient(credentials, GITLAB_PROJECT_ID)
+// 	// user, _, _ := gitlab.client.Users.CurrentUser()
+// 	// fmt.Printf("Created client for username: %v", user)
+// }
 
-	// user, _, _ := gitlab.client.Users.CurrentUser()
-	// fmt.Printf("Created client for username: %v", user)
-}
+// func TestGetSecret(t *testing.T) {
+// 	ctx := context.Background()
 
-func TestGetSecret(t *testing.T) {
-	ctx := context.Background()
+// 	ref := v1alpha1.ExternalSecretDataRemoteRef{Key: "mySecretBanana"}
 
-	ref := v1alpha1.ExternalSecretDataRemoteRef{Key: "mySecretBanana"}
+// 	credentials := GitlabCredentials{Token: GITLAB_TOKEN}
+// 	gitlab := NewGitlabProvider()
+// 	gitlab.SetAuth(credentials, GITLAB_PROJECT_ID)
 
-	credentials := GitlabCredentials{Token: GITLAB_TOKEN}
-	gitlab := NewGitlabProvider()
-	gitlab.NewGitlabClient(credentials, GITLAB_PROJECT_ID)
+// 	secretData, err := gitlab.GetSecret(ctx, ref)
 
-	secretData, err := gitlab.GetSecret(ctx, ref)
+// 	if err != nil {
+// 		fmt.Errorf("error retrieving secret, %w", err)
+// 	}
 
-	if err != nil {
-		fmt.Printf("that's an error, Charlie. %v", err)
-	}
+// 	fmt.Printf("Got secret data %v", string(secretData))
+// }
 
-	fmt.Printf("Got secret data %v", string(secretData))
-}
+// func TestGetSecretMap(t *testing.T) {
+// 	ctx := context.Background()
 
-func TestGetSecretMap(t *testing.T) {
-	ctx := context.Background()
+// 	ref := v1alpha1.ExternalSecretDataRemoteRef{Key: "myJsonSecret"}
 
-	ref := v1alpha1.ExternalSecretDataRemoteRef{Key: "myJsonSecret"}
+// 	credentials := GitlabCredentials{Token: GITLAB_TOKEN}
+// 	gitlab := NewGitlabProvider()
+// 	gitlab.SetAuth(credentials, GITLAB_PROJECT_ID)
 
-	credentials := GitlabCredentials{Token: GITLAB_TOKEN}
-	gitlab := NewGitlabProvider()
-	gitlab.NewGitlabClient(credentials, GITLAB_PROJECT_ID)
+// 	secretData, err := gitlab.GetSecretMap(ctx, ref)
 
-	secretData, err := gitlab.GetSecretMap(ctx, ref)
+// 	if err != nil {
+// 		fmt.Errorf("error retrieving secret map, %w", err)
+// 	}
 
-	if err != nil {
-		fmt.Errorf("that's an error, Charlie. %w", err)
-	}
-
-	fmt.Printf("Got secret map: %v", secretData)
-}
+// 	fmt.Printf("Got secret map: %v", secretData)
+// }

+ 1 - 0
pkg/provider/register/register.go

@@ -20,6 +20,7 @@ import (
 	_ "github.com/external-secrets/external-secrets/pkg/provider/aws"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager"
+	_ "github.com/external-secrets/external-secrets/pkg/provider/gitlab"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/ibm"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/vault"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/yandex/lockbox"

+ 1 - 1
pkg/provider/schema/schema.go

@@ -92,7 +92,7 @@ func GetProvider(s esv1alpha1.GenericStore) (provider.Provider, error) {
 // or an error if the provider is not configured.
 func getProviderName(storeSpec *esv1alpha1.SecretStoreProvider) (string, error) {
 	storeBytes, err := json.Marshal(storeSpec)
-	if err != nil {
+	if err != nil || storeBytes == nil {
 		return "", fmt.Errorf("failed to marshal store spec: %w", err)
 	}