diff --git a/api/v1alpha1/auth_types.go b/api/v1alpha1/auth_types.go new file mode 100644 index 00000000..06ce2e5f --- /dev/null +++ b/api/v1alpha1/auth_types.go @@ -0,0 +1,20 @@ +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" +) + +type AuthOptions struct { + Anonymous bool `json:"anonymous"` + AccessToken *AccessTokenAuth `json:"access_token"` + StaticCredentials *StaticCredentialsAuth `json:"static_credentials"` +} + +type AccessTokenAuth struct { + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` +} + +type StaticCredentialsAuth struct { + Username string `json:"username,omitempty"` + SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef"` +} diff --git a/api/v1alpha1/storage_types.go b/api/v1alpha1/storage_types.go index d63b093a..08c4a380 100644 --- a/api/v1alpha1/storage_types.go +++ b/api/v1alpha1/storage_types.go @@ -27,6 +27,11 @@ type StorageSpec struct { // +required DataStore []corev1.PersistentVolumeClaimSpec `json:"dataStore"` + // (Optional) Auth services parameter overrides + // Default: (not specified) + // +optional + Auth *AuthOptions `json:"auth,omitempty"` + // (Optional) Storage services parameter overrides // Default: (not specified) // +optional diff --git a/api/v1alpha1/storage_webhook.go b/api/v1alpha1/storage_webhook.go index d09d7815..00b4a41b 100644 --- a/api/v1alpha1/storage_webhook.go +++ b/api/v1alpha1/storage_webhook.go @@ -1,8 +1,10 @@ package v1alpha1 import ( + "errors" "fmt" + "gopkg.in/yaml.v3" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/strings/slices" @@ -20,6 +22,14 @@ func (r *Storage) SetupWebhookWithManager(mgr ctrl.Manager) error { Complete() } +type YDBConfiguration struct { + DomainsConfig struct { + SecurityConfig struct { + EnforceUserTokenRequirement bool `yaml:"enforce_user_token_requirement"` + } `yaml:"security_config"` + } `yaml:"domains_config"` +} + //+kubebuilder:webhook:path=/mutate-ydb-tech-v1alpha1-storage,mutating=true,failurePolicy=fail,sideEffects=None,groups=ydb.tech,resources=storages,verbs=create;update,versions=v1alpha1,name=mutate-storage.ydb.tech,admissionReviewVersions=v1 var _ webhook.Defaulter = &Storage{} @@ -54,6 +64,12 @@ func (r *Storage) Default() { } } + if r.Spec.Auth == nil { + r.Spec.Auth = &AuthOptions{ + Anonymous: true, + } + } + if r.Spec.Domain == "" { r.Spec.Domain = "root" // FIXME } @@ -88,6 +104,22 @@ func (r *Storage) ValidateCreate() error { } } + yamlConfig := YDBConfiguration{} + err := yaml.Unmarshal([]byte(r.Spec.Configuration), &yamlConfig) + if err != nil { + return errors.New("failed parse 'spec.configuration' to determine `enforce_user_token_requirement`") + } + + if yamlConfig.DomainsConfig.SecurityConfig.EnforceUserTokenRequirement { + if r.Spec.Auth.Anonymous { + return errors.New("field 'spec.auth' does not satisfy with config option `enforce_user_token_requirement: true`") + } + } else { + if !r.Spec.Auth.Anonymous { + return errors.New("field 'spec.auth' does not satisfy with config option `enforce_user_token_requirement: false` ") + } + } + // TODO(user): fill in your validation logic upon object creation. return nil } @@ -96,6 +128,22 @@ func (r *Storage) ValidateCreate() error { func (r *Storage) ValidateUpdate(old runtime.Object) error { storagelog.Info("validate update", "name", r.Name) + yamlConfig := YDBConfiguration{} + err := yaml.Unmarshal([]byte(r.Spec.Configuration), &yamlConfig) + if err != nil { + return errors.New("failed to parse 'spec.configuration' to determine `enforce_user_token_requirement`") + } + + if yamlConfig.DomainsConfig.SecurityConfig.EnforceUserTokenRequirement { + if r.Spec.Auth.Anonymous { + return errors.New("empty field 'spec.auth' does not satisfy with config option `enforce_user_token_requirement: true`") + } + } else { + if !r.Spec.Auth.Anonymous { + return errors.New("field 'spec.auth' does not satisfy with config option `enforce_user_token_requirement: false` ") + } + } + // TODO(user): fill in your validation logic upon object update. return nil } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 9c9ce2d9..ab17db1d 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -12,6 +12,51 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AccessTokenAuth) DeepCopyInto(out *AccessTokenAuth) { + *out = *in + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessTokenAuth. +func (in *AccessTokenAuth) DeepCopy() *AccessTokenAuth { + if in == nil { + return nil + } + out := new(AccessTokenAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthOptions) DeepCopyInto(out *AuthOptions) { + *out = *in + if in.AccessToken != nil { + in, out := &in.AccessToken, &out.AccessToken + *out = new(AccessTokenAuth) + (*in).DeepCopyInto(*out) + } + if in.StaticCredentials != nil { + in, out := &in.StaticCredentials, &out.StaticCredentials + *out = new(StaticCredentialsAuth) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthOptions. +func (in *AuthOptions) DeepCopy() *AuthOptions { + if in == nil { + return nil + } + out := new(AuthOptions) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Database) DeepCopyInto(out *Database) { *out = *in @@ -450,6 +495,26 @@ func (in *SharedDatabaseRef) DeepCopy() *SharedDatabaseRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StaticCredentialsAuth) DeepCopyInto(out *StaticCredentialsAuth) { + *out = *in + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StaticCredentialsAuth. +func (in *StaticCredentialsAuth) DeepCopy() *StaticCredentialsAuth { + if in == nil { + return nil + } + out := new(StaticCredentialsAuth) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StatusService) DeepCopyInto(out *StatusService) { *out = *in @@ -568,6 +633,11 @@ func (in *StorageSpec) DeepCopyInto(out *StorageSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Auth != nil { + in, out := &in.Auth, &out.Auth + *out = new(AuthOptions) + (*in).DeepCopyInto(*out) + } in.Service.DeepCopyInto(&out.Service) in.Resources.DeepCopyInto(&out.Resources) in.Image.DeepCopyInto(&out.Image) @@ -698,3 +768,19 @@ func (in *TLSConfiguration) DeepCopy() *TLSConfiguration { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *YDBConfiguration) DeepCopyInto(out *YDBConfiguration) { + *out = *in + out.DomainsConfig = in.DomainsConfig +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new YDBConfiguration. +func (in *YDBConfiguration) DeepCopy() *YDBConfiguration { + if in == nil { + return nil + } + out := new(YDBConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/deploy/ydb-operator/crds/storage.yaml b/deploy/ydb-operator/crds/storage.yaml index 0dc674d6..f641a0ef 100644 --- a/deploy/ydb-operator/crds/storage.yaml +++ b/deploy/ydb-operator/crds/storage.yaml @@ -881,6 +881,63 @@ spec: type: array type: object type: object + auth: + description: '(Optional) Auth services parameter overrides Default: + (not specified)' + properties: + access_token: + properties: + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + anonymous: + type: boolean + static_credentials: + properties: + secretKeyRef: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + username: + type: string + required: + - secretKeyRef + type: object + required: + - access_token + - anonymous + - static_credentials + type: object caBundle: description: User-defined root certificate authority that is added to system trust store of Storage pods on startup. diff --git a/go.mod b/go.mod index 1fd74029..0ea6e7c8 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/go-logr/logr v0.4.0 github.com/pkg/errors v0.9.1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.50.0 - github.com/ydb-platform/ydb-go-genproto v0.0.0-20221215182650-986f9d10542f + github.com/ydb-platform/ydb-go-genproto v0.0.0-20230528143953-42c825ace222 google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v3 v3.0.0 k8s.io/api v0.22.1 @@ -20,8 +20,13 @@ require ( require ( cloud.google.com/go/compute v1.13.0 // indirect cloud.google.com/go/compute/metadata v0.2.1 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v4 v4.4.3 // indirect github.com/jonboulle/clockwork v0.3.0 // indirect + github.com/yandex-cloud/go-genproto v0.0.0-20211115083454-9ca41db5ed9e // indirect + github.com/ydb-platform/ydb-go-sdk-auth-environ v0.2.0 // indirect + github.com/ydb-platform/ydb-go-yc v0.10.2 // indirect + github.com/ydb-platform/ydb-go-yc-metadata v0.5.2 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/grpc v1.52.0 // indirect @@ -60,16 +65,16 @@ require ( github.com/prometheus/common v0.26.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/ydb-platform/ydb-go-sdk/v3 v3.42.4 + github.com/ydb-platform/ydb-go-sdk/v3 v3.47.3 go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.0 - golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect - golang.org/x/net v0.5.0 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 5703b9ae..3e0b6da7 100644 --- a/go.sum +++ b/go.sum @@ -102,6 +102,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= @@ -148,6 +149,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= @@ -237,6 +239,9 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -253,6 +258,7 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -476,6 +482,7 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rekby/fixenv v0.3.2/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -520,6 +527,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -530,13 +538,28 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yandex-cloud/go-genproto v0.0.0-20211115083454-9ca41db5ed9e h1:9LPdmD1vqadsDQUva6t2O9MbnyvoOgo8nFNPaOIH5U8= +github.com/yandex-cloud/go-genproto v0.0.0-20211115083454-9ca41db5ed9e/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20220203104745-929cf9c248bc/go.mod h1:cc138nptTn9eKptCQl/grxP6pBKpo/bnXDiOxuVZtps= github.com/ydb-platform/ydb-go-genproto v0.0.0-20221215182650-986f9d10542f h1:BBczNIM1MJHT7XkIUA8pThXWxJvxoBjcWvne3xwe2RI= github.com/ydb-platform/ydb-go-genproto v0.0.0-20221215182650-986f9d10542f/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20230528143953-42c825ace222 h1:8ddsk8HKBkVPH8w3k81si6SeCVJIAtw8dnw+s3h0ciE= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20230528143953-42c825ace222/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= +github.com/ydb-platform/ydb-go-sdk-auth-environ v0.2.0 h1:IG5bPd+Lqyc+zsw2kmxqfGLkaDHuAEnWX63/8RBBiA4= +github.com/ydb-platform/ydb-go-sdk-auth-environ v0.2.0/go.mod h1:l6lZ+osdQOjDRBgRA4PQ06BuvmXN2neYjnRw8rCfd7s= +github.com/ydb-platform/ydb-go-sdk/v3 v3.25.3/go.mod h1:PFizF/vJsdAgEwjK3DVSBD52kdmRkWfSIS2q2pA+e88= github.com/ydb-platform/ydb-go-sdk/v3 v3.42.4 h1:pUPJYkLFoXn2nRKazNdHwgOwR1e5XWOyqNQUT4dEV2Q= github.com/ydb-platform/ydb-go-sdk/v3 v3.42.4/go.mod h1:9Y49weCjXl698kMDAvnm6CmwtdoYckVtlahS4TH1Tiw= +github.com/ydb-platform/ydb-go-sdk/v3 v3.47.3 h1:6LwpXivkQxKYRjSZYj4M+G3J8sDtPPNzo9Shzc64oIo= +github.com/ydb-platform/ydb-go-sdk/v3 v3.47.3/go.mod h1:bWnOIcUHd7+Sl7DN+yhyY1H/I61z53GczvwJgXMgvj0= +github.com/ydb-platform/ydb-go-yc v0.10.2 h1:RAHy6g7ncxk1y0N4oS2MwYXLATqRqKBI6DYXuxpV2wo= +github.com/ydb-platform/ydb-go-yc v0.10.2/go.mod h1:U1dX3LJy6zADId2DciCXlgrU/vphK1+CQzaefKq21dQ= +github.com/ydb-platform/ydb-go-yc-metadata v0.5.2 h1:nMtixUijP0Z7iHJNT9fOL+dbmEzZxqU6Xk87ll7hqXg= +github.com/ydb-platform/ydb-go-yc-metadata v0.5.2/go.mod h1:82SQ4L3PewiEmFW4oTMc1sfPjODasIYxD/SKGsbK74s= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -596,6 +619,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -629,6 +654,7 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -665,11 +691,15 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/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= @@ -686,6 +716,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -742,15 +773,23 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -759,8 +798,11 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -813,8 +855,10 @@ golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -863,6 +907,7 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -879,7 +924,10 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/internal/cms/tenant.go b/internal/cms/tenant.go index 6a80ed59..49a7e5cf 100644 --- a/internal/cms/tenant.go +++ b/internal/cms/tenant.go @@ -11,6 +11,7 @@ import ( "github.com/ydb-platform/ydb-go-sdk/v3" "sigs.k8s.io/controller-runtime/pkg/log" + ydbCredentials "github.com/ydb-platform/ydb-go-sdk/v3/credentials" ydbv1alpha1 "github.com/ydb-platform/ydb-kubernetes-operator/api/v1alpha1" "github.com/ydb-platform/ydb-kubernetes-operator/internal/connection" "github.com/ydb-platform/ydb-kubernetes-operator/internal/resources" @@ -26,9 +27,16 @@ type Tenant struct { SharedDatabasePath string } -func (t *Tenant) Create(ctx context.Context, database *resources.DatabaseBuilder) error { +func (t *Tenant) Create(ctx context.Context, database *resources.DatabaseBuilder, credentials ydbCredentials.Credentials) error { createDatabaseURL := fmt.Sprintf("%s/%s", t.StorageEndpoint, database.Spec.Domain) - db, err := connection.Build(ctx, createDatabaseURL) + conn := connection.NewYDBConnection( + ctx, + createDatabaseURL, + resources.IsGrpcSecure(database.Storage), + credentials, + ) + + db, err := conn.Open() if err != nil { return err } @@ -36,7 +44,7 @@ func (t *Tenant) Create(ctx context.Context, database *resources.DatabaseBuilder logger := log.FromContext(ctx) defer func() { - connection.Close(ctx, db) + conn.Close(db) }() client := Ydb_Cms_V1.NewCmsServiceClient(ydb.GRPCConn(db)) diff --git a/internal/connection/connection.go b/internal/connection/connection.go index ca922b30..80db28a6 100644 --- a/internal/connection/connection.go +++ b/internal/connection/connection.go @@ -8,65 +8,36 @@ import ( "github.com/ydb-platform/ydb-go-sdk/v3" ydbCredentials "github.com/ydb-platform/ydb-go-sdk/v3/credentials" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/credentials/insecure" "sigs.k8s.io/controller-runtime/pkg/log" ) -const ( - DefaultRootUsername = "root" - DefaultRootPassword = "" -) - -func buildSystemTLSStoreOption() grpc.DialOption { - certPool, _ := x509.SystemCertPool() - // TODO(shmel1k@): figure out min allowed TLS version? - tlsCredentials := credentials.NewTLS(&tls.Config{ //nolint - RootCAs: certPool, - }) - return grpc.WithTransportCredentials(tlsCredentials) +type YDBConnection struct { + ctx context.Context + endpoint string + secure bool + credentials ydbCredentials.Credentials } -func buildConnectionOpts(secure bool) []grpc.DialOption { - var opts []grpc.DialOption - - if secure { - opts = append(opts, buildSystemTLSStoreOption()) - } else { - opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) +func NewYDBConnection(ctx context.Context, endpoint string, secure bool, credentials ydbCredentials.Credentials) *YDBConnection { + return &YDBConnection{ + ctx: ctx, + endpoint: endpoint, + secure: secure, + credentials: credentials, } - - return opts } -func GetAuthToken(ctx context.Context, grpcEndpoint string, secure bool) (string, error) { - staticCredentials := ydbCredentials.NewStaticCredentials( - DefaultRootUsername, - DefaultRootPassword, - grpcEndpoint, - buildConnectionOpts(secure)..., - ) - - token, err := staticCredentials.Token(ctx) - if err != nil { - return "", err - } - - return token, nil -} - -func Build(ctx context.Context, grpcEndpointWithProto string) (ydb.Connection, error) { +func (conn *YDBConnection) Open() (*ydb.Driver, error) { db, err := ydb.Open( - ctx, - grpcEndpointWithProto, - ydb.WithStaticCredentials(DefaultRootUsername, DefaultRootPassword), + conn.ctx, + conn.endpoint, + conn.getOptions()..., ) if err != nil { - log.FromContext(ctx).Error(err, + log.FromContext(conn.ctx).Error(err, fmt.Sprintf( "Failed to open grpc connection to YDB, endpoint %s", - grpcEndpointWithProto, + conn.endpoint, )) return nil, err } @@ -74,9 +45,27 @@ func Build(ctx context.Context, grpcEndpointWithProto string) (ydb.Connection, e return db, nil } -func Close(ctx context.Context, db ydb.Connection) { - logger := log.FromContext(ctx) - if err := db.Close(ctx); err != nil { +func (conn *YDBConnection) Close(db *ydb.Driver) { + logger := log.FromContext(conn.ctx) + if err := db.Close(conn.ctx); err != nil { logger.Error(err, "db close failed") } } + +func (conn *YDBConnection) getOptions() []ydb.Option { + var opts []ydb.Option + + opts = append(opts, ydb.WithCredentials(conn.credentials)) + + if conn.secure { + certPool, _ := x509.SystemCertPool() + // TODO(shmel1k@): figure out min allowed TLS version? + opts = append(opts, ydb.WithTLSConfig(&tls.Config{ //nolint + RootCAs: certPool, + })) + } else { + opts = append(opts, ydb.WithTLSSInsecureSkipVerify()) + } + + return opts +} diff --git a/internal/controllers/database/controller.go b/internal/controllers/database/controller.go index 895b32d7..ba933424 100644 --- a/internal/controllers/database/controller.go +++ b/internal/controllers/database/controller.go @@ -34,12 +34,13 @@ type Reconciler struct { //+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core,resources=services/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core,resources=services/finalizers,verbs=get;list;watch +//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core,resources=configmaps/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=apps,resources=secrets,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=apps,resources=secrets/status,verbs=get;update;patch //+kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=apps,resources=statefulsets/status,verbs=get;update;patch //+kubebuilder:rbac:groups=apps,resources=statefulsets/finalizers,verbs=get;list;watch -//+kubebuilder:rbac:groups=apps,resources=secrets,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=apps,resources=secrets/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=apps,resources=secrets/finalizers,verbs=get;list;watch // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. diff --git a/internal/controllers/database/sync.go b/internal/controllers/database/sync.go index 904b79ed..f39ff22f 100644 --- a/internal/controllers/database/sync.go +++ b/internal/controllers/database/sync.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + ydbCredentials "github.com/ydb-platform/ydb-go-sdk/v3/credentials" ydbv1alpha1 "github.com/ydb-platform/ydb-kubernetes-operator/api/v1alpha1" "github.com/ydb-platform/ydb-kubernetes-operator/internal/cms" "github.com/ydb-platform/ydb-kubernetes-operator/internal/labels" @@ -38,6 +39,9 @@ const ( TenantInitializedReasonInProgress = "InProgres" TenantInitializedReasonCompleted = "Completed" + DefaulRootUsername = "root" + DefaulRootPassword = "" + Stop = true Continue = false ) @@ -381,7 +385,13 @@ func (r *Reconciler) handleTenantCreation( SharedDatabasePath: sharedDatabasePath, } - err := tenant.Create(ctx, database) + credentials, err := r.getAuthCredentials(ctx, database) + if err != nil { + r.Log.Error(err, "Error connecting to YDB storage %s", database.Storage.Name) + return Stop, ctrl.Result{RequeueAfter: TenantCreationRequeueDelay}, err + } + + err = tenant.Create(ctx, database, credentials) if err != nil { r.Recorder.Event( database, @@ -445,3 +455,64 @@ func (r *Reconciler) setState( return Stop, ctrl.Result{RequeueAfter: StatusUpdateRequeueDelay}, nil } + +func (r *Reconciler) getAuthCredentials( + ctx context.Context, + database *resources.DatabaseBuilder, +) (ydbCredentials.Credentials, error) { + switch auth := database.Storage.Spec.Auth; { + case auth.AccessToken != nil: + token, err := r.getSecretKey( + ctx, + database.Storage.Namespace, + auth.AccessToken.SecretKeyRef, + ) + if err != nil { + return nil, err + } + return ydbCredentials.NewAccessTokenCredentials(token), nil + case auth.StaticCredentials != nil: + endpoint := database.GetStorageEndpointWithProto() + opts := resources.GetStorageGRPCOptions(database.Storage) + username := auth.StaticCredentials.Username + password := DefaulRootPassword + if auth.StaticCredentials.SecretKeyRef != nil { + var err error + password, err = r.getSecretKey( + ctx, + database.Storage.Namespace, + auth.StaticCredentials.SecretKeyRef, + ) + if err != nil { + return nil, err + } + } + return ydbCredentials.NewStaticCredentials(username, password, endpoint, opts...), nil + default: + return ydbCredentials.NewAnonymousCredentials(), nil + } +} + +func (r *Reconciler) getSecretKey( + ctx context.Context, + namespace string, + secretKeyRef *corev1.SecretKeySelector, +) (string, error) { + secret := &corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ + Name: secretKeyRef.Name, + Namespace: namespace, + }, secret) + if err != nil { + return "", err + } + secretVal, exist := secret.Data[secretKeyRef.Key] + if !exist { + return "", fmt.Errorf( + "key %s does not exist in secretData %s", + secretKeyRef.Key, + secretKeyRef.Name, + ) + } + return string(secretVal), nil +} diff --git a/internal/controllers/storage/controller.go b/internal/controllers/storage/controller.go index 73cdc417..6283addb 100644 --- a/internal/controllers/storage/controller.go +++ b/internal/controllers/storage/controller.go @@ -39,6 +39,8 @@ type Reconciler struct { //+kubebuilder:rbac:groups=core,resources=services/finalizers,verbs=get;list;watch //+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core,resources=configmaps/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core,resources=secrets/status,verbs=get;update;patch //+kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=apps,resources=statefulsets/status,verbs=get;update;patch //+kubebuilder:rbac:groups=apps,resources=statefulsets/finalizers,verbs=get;list;watch diff --git a/internal/controllers/storage/init.go b/internal/controllers/storage/init.go index 38872abc..8ce2c14b 100644 --- a/internal/controllers/storage/init.go +++ b/internal/controllers/storage/init.go @@ -5,14 +5,12 @@ import ( "fmt" "regexp" - "gopkg.in/yaml.v3" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "github.com/ydb-platform/ydb-kubernetes-operator/api/v1alpha1" - "github.com/ydb-platform/ydb-kubernetes-operator/internal/connection" "github.com/ydb-platform/ydb-kubernetes-operator/internal/exec" "github.com/ydb-platform/ydb-kubernetes-operator/internal/resources" ) @@ -103,14 +101,6 @@ func (r *Reconciler) setInitialStatus( return Continue, ctrl.Result{Requeue: false}, nil } -type PartialYamlConfig struct { - DomainsConfig struct { - SecurityConfig struct { - EnforceUserTokenRequirement bool `yaml:"enforce_user_token_requirement"` - } `yaml:"security_config"` - } `yaml:"domains_config"` -} - func (r *Reconciler) runInitScripts( ctx context.Context, storage *resources.StorageClusterBuilder, @@ -140,32 +130,27 @@ func (r *Reconciler) runInitScripts( cmd := []string{ fmt.Sprintf("%s/%s", v1alpha1.BinariesDir, v1alpha1.DaemonBinaryName), } - if resources.IsGrpcSecure(storage.Storage) { - cmd = append( - cmd, - "-s", storage.GetGRPCEndpointWithProto(), - ) + + // Append server address to connect + cmd = append( + cmd, + "-s", storage.GetGRPCEndpointWithProto(), + ) + + credentials, err := r.getAuthCredentials(ctx, storage) + if err != nil { + r.Log.Error(err, "Error connecting to YDB storage %s", storage.Name) + return Stop, ctrl.Result{RequeueAfter: StorageInitializationRequeueDelay}, err } - yamlConfig := PartialYamlConfig{} - err := yaml.Unmarshal([]byte(storage.Spec.Configuration), &yamlConfig) + token, err := credentials.Token(ctx) if err != nil { - r.Log.Error(err, "Failed to parse YAML to determine `enforce_user_token_requirement`") - // TODO(@tarasov-egor) Parse Configuration once, somewhere in webhook, and fail to apply - // if something's missing. Here is not the place to fail!!!! + r.Log.Error(err, "Error getting token for YDB credentials %s", storage.Name) return Stop, ctrl.Result{RequeueAfter: StorageInitializationRequeueDelay}, err } - if yamlConfig.DomainsConfig.SecurityConfig.EnforceUserTokenRequirement { - token, authErr := connection.GetAuthToken( - ctx, - storage.GetGRPCEndpoint(), - resources.IsGrpcSecure(storage.Storage), - ) - if authErr != nil { - r.Log.Error(authErr, "Failed to get auth token for blobstorage initialization") - return Stop, ctrl.Result{RequeueAfter: StorageInitializationRequeueDelay}, authErr - } + // Append security token if necessary + if token != "" { cmd = append( cmd, "--token", diff --git a/internal/controllers/storage/sync.go b/internal/controllers/storage/sync.go index 8abbe610..5c5d41f7 100644 --- a/internal/controllers/storage/sync.go +++ b/internal/controllers/storage/sync.go @@ -16,6 +16,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + ydbCredentials "github.com/ydb-platform/ydb-go-sdk/v3/credentials" ydbv1alpha1 "github.com/ydb-platform/ydb-kubernetes-operator/api/v1alpha1" "github.com/ydb-platform/ydb-kubernetes-operator/internal/healthcheck" "github.com/ydb-platform/ydb-kubernetes-operator/internal/labels" @@ -56,6 +57,9 @@ const ( Stop = true Continue = false + DefaulRootUsername = "root" + DefaulRootPassword = "" + annotationSkipInitialization = "ydb.tech/skip-initialization" ) @@ -231,8 +235,13 @@ func (r *Reconciler) runSelfCheck( storage *resources.StorageClusterBuilder, waitForGoodResultWithoutIssues bool, ) (bool, ctrl.Result, error) { - r.Log.Info("running step runSelfCheck") - result, err := healthcheck.GetSelfCheckResult(ctx, storage) + credentials, err := r.getAuthCredentials(ctx, storage) + if err != nil { + r.Log.Error(err, "Error connecting to YDB storage %s", storage.Name) + return Stop, ctrl.Result{RequeueAfter: SelfCheckRequeueDelay}, err + } + + result, err := healthcheck.GetSelfCheckResult(ctx, storage, credentials) if err != nil { r.Log.Error(err, "GetSelfCheckResult error") return Stop, ctrl.Result{RequeueAfter: SelfCheckRequeueDelay}, err @@ -281,3 +290,66 @@ func (r *Reconciler) setState( return Stop, ctrl.Result{RequeueAfter: StatusUpdateRequeueDelay}, nil } + +// getCredentials +func (r *Reconciler) getAuthCredentials( + ctx context.Context, + storage *resources.StorageClusterBuilder, +) (ydbCredentials.Credentials, error) { + switch auth := storage.Spec.Auth; { + case auth.AccessToken != nil: + token, err := r.getSecretKey( + ctx, + storage.Namespace, + auth.AccessToken.SecretKeyRef, + ) + if err != nil { + return nil, err + } + return ydbCredentials.NewAccessTokenCredentials(token), nil + case auth.StaticCredentials != nil: + endpoint := storage.GetGRPCEndpointWithProto() + opts := resources.GetStorageGRPCOptions(storage.Storage) + username := auth.StaticCredentials.Username + password := DefaulRootPassword + if auth.StaticCredentials.SecretKeyRef != nil { + var err error + password, err = r.getSecretKey( + ctx, + storage.Namespace, + auth.StaticCredentials.SecretKeyRef, + ) + if err != nil { + return nil, err + } + } + return ydbCredentials.NewStaticCredentials(username, password, endpoint, opts...), nil + default: + return ydbCredentials.NewAnonymousCredentials(), nil + } +} + +// getSecretKeyRef +func (r *Reconciler) getSecretKey( + ctx context.Context, + namespace string, + secretKeyRef *corev1.SecretKeySelector, +) (string, error) { + secret := &corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ + Name: secretKeyRef.Name, + Namespace: namespace, + }, secret) + if err != nil { + return "", err + } + secretVal, exist := secret.Data[secretKeyRef.Key] + if !exist { + return "", fmt.Errorf( + "key %s does not exist in secretData %s", + secretKeyRef.Key, + secretKeyRef.Name, + ) + } + return string(secretVal), nil +} diff --git a/internal/healthcheck/healthcheck.go b/internal/healthcheck/healthcheck.go index adbe9af8..1bdf7ae6 100644 --- a/internal/healthcheck/healthcheck.go +++ b/internal/healthcheck/healthcheck.go @@ -10,18 +10,25 @@ import ( "google.golang.org/protobuf/proto" "sigs.k8s.io/controller-runtime/pkg/log" + ydbCredentials "github.com/ydb-platform/ydb-go-sdk/v3/credentials" "github.com/ydb-platform/ydb-kubernetes-operator/internal/connection" "github.com/ydb-platform/ydb-kubernetes-operator/internal/resources" ) -func GetSelfCheckResult(ctx context.Context, cluster *resources.StorageClusterBuilder) (*Ydb_Monitoring.SelfCheckResult, error) { +func GetSelfCheckResult(ctx context.Context, cluster *resources.StorageClusterBuilder, credentials ydbCredentials.Credentials) (*Ydb_Monitoring.SelfCheckResult, error) { getSelfCheckURL := fmt.Sprintf( "%s/%s", cluster.GetGRPCEndpointWithProto(), cluster.Storage.Spec.Domain, ) + conn := connection.NewYDBConnection( + ctx, + getSelfCheckURL, + resources.IsGrpcSecure(cluster.Storage), + credentials, + ) - db, err := connection.Build(ctx, getSelfCheckURL) + db, err := conn.Open() if err != nil { return nil, err } @@ -29,7 +36,7 @@ func GetSelfCheckResult(ctx context.Context, cluster *resources.StorageClusterBu logger := log.FromContext(ctx) defer func() { - connection.Close(ctx, db) + conn.Close(db) }() client := Ydb_Monitoring_V1.NewMonitoringServiceClient(ydb.GRPCConn(db)) diff --git a/internal/resources/storage.go b/internal/resources/storage.go index 1b83972f..29226355 100644 --- a/internal/resources/storage.go +++ b/internal/resources/storage.go @@ -1,8 +1,13 @@ package resources import ( + "crypto/tls" + "crypto/x509" "fmt" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" @@ -53,6 +58,22 @@ func (b *StorageClusterBuilder) GetGRPCEndpointWithProto() string { return fmt.Sprintf("%s%s", proto, b.GetGRPCEndpoint()) } +func GetStorageGRPCOptions(s *api.Storage) []grpc.DialOption { + var opts []grpc.DialOption + if IsGrpcSecure(s) { + certPool, _ := x509.SystemCertPool() + // TODO(shmel1k@): figure out min allowed TLS version? + tlsCredentials := credentials.NewTLS(&tls.Config{ //nolint + RootCAs: certPool, + }) + opts = append(opts, grpc.WithTransportCredentials(tlsCredentials)) + } else { + opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) + } + + return opts +} + func IsGrpcSecure(s *api.Storage) bool { return s.Spec.Service.GRPC.TLSConfiguration != nil && s.Spec.Service.GRPC.TLSConfiguration.Enabled }