diff --git a/api/backup_storage.go b/api/backup_storage.go index 04f4bbb8..b9317405 100644 --- a/api/backup_storage.go +++ b/api/backup_storage.go @@ -41,12 +41,13 @@ func (e *EverestServer) ListBackupStorages(ctx echo.Context) error { for _, bs := range backupList.Items { s := bs result = append(result, BackupStorage{ - Type: BackupStorageType(bs.Spec.Type), - Name: s.Name, - Description: &s.Spec.Description, - BucketName: s.Spec.Bucket, - Region: s.Spec.Region, - Url: &s.Spec.EndpointURL, + Type: BackupStorageType(bs.Spec.Type), + Name: s.Name, + Description: &s.Spec.Description, + BucketName: s.Spec.Bucket, + Region: s.Spec.Region, + Url: &s.Spec.EndpointURL, + TargetNamespaces: s.Spec.TargetNamespaces, }) } @@ -55,7 +56,15 @@ func (e *EverestServer) ListBackupStorages(ctx echo.Context) error { // CreateBackupStorage creates a new backup storage object. func (e *EverestServer) CreateBackupStorage(ctx echo.Context) error { //nolint:funlen - params, err := validateCreateBackupStorageRequest(ctx, e.l) + namespaces, err := e.kubeClient.GetWatchedNamespaces(ctx.Request().Context(), e.kubeClient.Namespace()) + if err != nil { + e.l.Error(err) + return ctx.JSON(http.StatusInternalServerError, Error{ + Message: pointer.ToString("Failed getting watched namespaces"), + }) + } + + params, err := validateCreateBackupStorageRequest(ctx, namespaces, e.l) if err != nil { return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())}) } @@ -111,6 +120,7 @@ func (e *EverestServer) CreateBackupStorage(ctx echo.Context) error { //nolint:f Bucket: params.BucketName, Region: params.Region, CredentialsSecretName: params.Name, + TargetNamespaces: params.TargetNamespaces, }, } if params.Url != nil { @@ -134,12 +144,13 @@ func (e *EverestServer) CreateBackupStorage(ctx echo.Context) error { //nolint:f }) } result := BackupStorage{ - Type: BackupStorageType(params.Type), - Name: params.Name, - Description: params.Description, - BucketName: params.BucketName, - Region: params.Region, - Url: params.Url, + Type: BackupStorageType(params.Type), + Name: params.Name, + Description: params.Description, + BucketName: params.BucketName, + Region: params.Region, + Url: params.Url, + TargetNamespaces: params.TargetNamespaces, } return ctx.JSON(http.StatusOK, result) @@ -208,17 +219,18 @@ func (e *EverestServer) GetBackupStorage(ctx echo.Context, backupStorageName str }) } return ctx.JSON(http.StatusOK, BackupStorage{ - Type: BackupStorageType(s.Spec.Type), - Name: s.Name, - Description: &s.Spec.Description, - BucketName: s.Spec.Bucket, - Region: s.Spec.Region, - Url: &s.Spec.EndpointURL, + Type: BackupStorageType(s.Spec.Type), + Name: s.Name, + Description: &s.Spec.Description, + BucketName: s.Spec.Bucket, + Region: s.Spec.Region, + Url: &s.Spec.EndpointURL, + TargetNamespaces: s.Spec.TargetNamespaces, }) } // UpdateBackupStorage updates of the specified backup storage. -func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName string) error { //nolint:funlen +func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName string) error { //nolint:funlen,cyclop c := ctx.Request().Context() bs, err := e.kubeClient.GetBackupStorage(c, backupStorageName) if err != nil { @@ -232,6 +244,7 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName Message: pointer.ToString("Failed getting backup storage"), }) } + secret, err := e.kubeClient.GetSecret(c, backupStorageName) if err != nil { if k8serrors.IsNotFound(err) { @@ -244,7 +257,16 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName Message: pointer.ToString("Failed getting secret"), }) } - params, err := validateUpdateBackupStorageRequest(ctx, bs, secret, e.l) + + namespaces, err := e.kubeClient.GetWatchedNamespaces(ctx.Request().Context(), e.kubeClient.Namespace()) + if err != nil { + e.l.Error(err) + return ctx.JSON(http.StatusInternalServerError, Error{ + Message: pointer.ToString("Failed getting watched namespaces"), + }) + } + + params, err := validateUpdateBackupStorageRequest(ctx, bs, secret, namespaces, e.l) if err != nil { return ctx.JSON(http.StatusBadRequest, Error{Message: pointer.ToString(err.Error())}) } @@ -276,6 +298,9 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName if params.Description != nil { bs.Spec.Description = *params.Description } + if params.TargetNamespaces != nil { + bs.Spec.TargetNamespaces = *params.TargetNamespaces + } err = e.kubeClient.UpdateBackupStorage(c, bs) if err != nil { @@ -285,12 +310,13 @@ func (e *EverestServer) UpdateBackupStorage(ctx echo.Context, backupStorageName }) } result := BackupStorage{ - Type: BackupStorageType(bs.Spec.Type), - Name: bs.Name, - Description: params.Description, - BucketName: bs.Spec.Bucket, - Region: bs.Spec.Region, - Url: &bs.Spec.EndpointURL, + Type: BackupStorageType(bs.Spec.Type), + Name: bs.Name, + Description: params.Description, + BucketName: bs.Spec.Bucket, + Region: bs.Spec.Region, + Url: &bs.Spec.EndpointURL, + TargetNamespaces: bs.Spec.TargetNamespaces, } return ctx.JSON(http.StatusOK, result) diff --git a/api/everest-server.gen.go b/api/everest-server.gen.go index 26522dd1..bf96b1e4 100644 --- a/api/everest-server.gen.go +++ b/api/everest-server.gen.go @@ -87,12 +87,15 @@ const ( // BackupStorage Backup storage information type BackupStorage struct { - BucketName string `json:"bucketName"` - Description *string `json:"description,omitempty"` - Name string `json:"name"` - Region string `json:"region,omitempty"` - Type BackupStorageType `json:"type"` - Url *string `json:"url,omitempty"` + BucketName string `json:"bucketName"` + Description *string `json:"description,omitempty"` + Name string `json:"name"` + Region string `json:"region,omitempty"` + + // TargetNamespaces List of namespaces allowed to use this backup storage + TargetNamespaces []string `json:"targetNamespaces"` + Type BackupStorageType `json:"type"` + Url *string `json:"url,omitempty"` } // BackupStorageType defines model for BackupStorage.Type. @@ -110,11 +113,14 @@ type CreateBackupStorageParams struct { Description *string `json:"description,omitempty"` // Name A user defined string name of the storage in the DNS name format https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names - Name string `json:"name"` - Region string `json:"region,omitempty"` - SecretKey string `json:"secretKey"` - Type CreateBackupStorageParamsType `json:"type"` - Url *string `json:"url,omitempty"` + Name string `json:"name"` + Region string `json:"region,omitempty"` + SecretKey string `json:"secretKey"` + + // TargetNamespaces List of namespaces allowed to use this backup storage + TargetNamespaces []string `json:"targetNamespaces"` + Type CreateBackupStorageParamsType `json:"type"` + Url *string `json:"url,omitempty"` } // CreateBackupStorageParamsType defines model for CreateBackupStorageParams.Type. @@ -714,7 +720,10 @@ type UpdateBackupStorageParams struct { Description *string `json:"description,omitempty"` Region *string `json:"region,omitempty"` SecretKey *string `json:"secretKey,omitempty"` - Url *string `json:"url,omitempty"` + + // TargetNamespaces List of namespaces allowed to use this backup storage + TargetNamespaces *[]string `json:"targetNamespaces,omitempty"` + Url *string `json:"url,omitempty"` } // Version Everest version info @@ -1917,140 +1926,140 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "//S/AQAA//+OeR6A7fUAAA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/everest_test.go b/api/everest_test.go index b67cdefc..1c9a0219 100644 --- a/api/everest_test.go +++ b/api/everest_test.go @@ -60,7 +60,7 @@ func TestBuildProxiedUrl(t *testing.T) { tc := testCase t.Run(tc.url, func(t *testing.T) { t.Parallel() - require.Equal(t, tc.expected, buildProxiedURL(tc.url, "percona-everest", tc.kind, tc.name)) + require.Equal(t, tc.expected, buildProxiedURL("percona-everest", tc.kind, tc.name)) }) } } diff --git a/api/proxy.go b/api/proxy.go index 10948f53..05340043 100644 --- a/api/proxy.go +++ b/api/proxy.go @@ -77,12 +77,12 @@ func (e *EverestServer) proxyKubernetes(ctx echo.Context, namespace, kind, name if namespace == "" { namespace = e.kubeClient.Namespace() } - req.URL.Path = buildProxiedURL(ctx.Request().URL.Path, namespace, kind, name) + req.URL.Path = buildProxiedURL(namespace, kind, name) reverseProxy.ServeHTTP(ctx.Response(), req) return nil } -func buildProxiedURL(uri, namespace, kind, name string) string { +func buildProxiedURL(namespace, kind, name string) string { proxiedURL := fmt.Sprintf( "/apis/everest.percona.com/v1alpha1/namespaces/%s/%s", url.PathEscape(strings.ReplaceAll(namespace, "/", "")), diff --git a/api/validation.go b/api/validation.go index 8e845eb0..f0af05e3 100644 --- a/api/validation.go +++ b/api/validation.go @@ -254,7 +254,44 @@ func azureAccess(ctx context.Context, l *zap.SugaredLogger, accountName, account return nil } -func validateUpdateBackupStorageRequest(ctx echo.Context, bs *everestv1alpha1.BackupStorage, secret *corev1.Secret, l *zap.SugaredLogger) (*UpdateBackupStorageParams, error) { +func validateTargetNamespaces(targetNamespaces, namespaces []string) error { + for _, targetNamespace := range targetNamespaces { + found := false + for _, namespace := range namespaces { + if targetNamespace == namespace { + found = true + break + } + } + if !found { + return fmt.Errorf("unknown namespace '%s'", targetNamespace) + } + } + + return nil +} + +func validateBackupStorageAccess(ctx echo.Context, sType string, url *string, bucketName, region, accessKey, secretKey string, l *zap.SugaredLogger) error { + switch sType { + case string(BackupStorageTypeS3): + if region == "" { + return errors.New("region is required when using S3 storage type") + } + if err := s3Access(l, url, accessKey, secretKey, bucketName, region); err != nil { + return err + } + case string(BackupStorageTypeAzure): + if err := azureAccess(ctx.Request().Context(), l, accessKey, secretKey, bucketName); err != nil { + return err + } + default: + return ErrUpdateStorageNotSupported(sType) + } + + return nil +} + +func validateUpdateBackupStorageRequest(ctx echo.Context, bs *everestv1alpha1.BackupStorage, secret *corev1.Secret, namespaces []string, l *zap.SugaredLogger) (*UpdateBackupStorageParams, error) { var params UpdateBackupStorageParams if err := ctx.Bind(¶ms); err != nil { return nil, err @@ -268,6 +305,13 @@ func validateUpdateBackupStorageRequest(ctx echo.Context, bs *everestv1alpha1.Ba } url = params.Url } + + if params.TargetNamespaces != nil { + if err := validateTargetNamespaces(*params.TargetNamespaces, namespaces); err != nil { + return nil, err + } + } + accessKey := string(secret.Data["AWS_ACCESS_KEY_ID"]) if params.AccessKey != nil { accessKey = *params.AccessKey @@ -281,30 +325,21 @@ func validateUpdateBackupStorageRequest(ctx echo.Context, bs *everestv1alpha1.Ba if params.BucketName != nil { bucketName = *params.BucketName } + region := bs.Spec.Region if params.Region != nil { region = *params.Region } - switch string(bs.Spec.Type) { - case string(BackupStorageTypeS3): - if params.Region != nil && *params.Region == "" { - return nil, errors.New("region is required when using S3 storage type") - } - if err := s3Access(l, url, accessKey, secretKey, bucketName, region); err != nil { - return nil, err - } - case string(BackupStorageTypeAzure): - if err := azureAccess(ctx.Request().Context(), l, accessKey, secretKey, bucketName); err != nil { - return nil, err - } - default: - return nil, ErrUpdateStorageNotSupported(string(bs.Spec.Type)) + + err := validateBackupStorageAccess(ctx, string(bs.Spec.Type), url, bucketName, region, accessKey, secretKey, l) + if err != nil { + return nil, err } return ¶ms, nil } -func validateCreateBackupStorageRequest(ctx echo.Context, l *zap.SugaredLogger) (*CreateBackupStorageParams, error) { +func validateCreateBackupStorageRequest(ctx echo.Context, namespaces []string, l *zap.SugaredLogger) (*CreateBackupStorageParams, error) { var params CreateBackupStorageParams if err := ctx.Bind(¶ms); err != nil { return nil, err @@ -327,6 +362,10 @@ func validateCreateBackupStorageRequest(ctx echo.Context, l *zap.SugaredLogger) } } + if err := validateTargetNamespaces(params.TargetNamespaces, namespaces); err != nil { + return nil, err + } + // check data access if err := validateStorageAccessByCreate(ctx.Request().Context(), params, l); err != nil { l.Error(err) diff --git a/client/everest-client.gen.go b/client/everest-client.gen.go index 710c863d..4d5b6394 100644 --- a/client/everest-client.gen.go +++ b/client/everest-client.gen.go @@ -88,12 +88,15 @@ const ( // BackupStorage Backup storage information type BackupStorage struct { - BucketName string `json:"bucketName"` - Description *string `json:"description,omitempty"` - Name string `json:"name"` - Region string `json:"region,omitempty"` - Type BackupStorageType `json:"type"` - Url *string `json:"url,omitempty"` + BucketName string `json:"bucketName"` + Description *string `json:"description,omitempty"` + Name string `json:"name"` + Region string `json:"region,omitempty"` + + // TargetNamespaces List of namespaces allowed to use this backup storage + TargetNamespaces []string `json:"targetNamespaces"` + Type BackupStorageType `json:"type"` + Url *string `json:"url,omitempty"` } // BackupStorageType defines model for BackupStorage.Type. @@ -111,11 +114,14 @@ type CreateBackupStorageParams struct { Description *string `json:"description,omitempty"` // Name A user defined string name of the storage in the DNS name format https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names - Name string `json:"name"` - Region string `json:"region,omitempty"` - SecretKey string `json:"secretKey"` - Type CreateBackupStorageParamsType `json:"type"` - Url *string `json:"url,omitempty"` + Name string `json:"name"` + Region string `json:"region,omitempty"` + SecretKey string `json:"secretKey"` + + // TargetNamespaces List of namespaces allowed to use this backup storage + TargetNamespaces []string `json:"targetNamespaces"` + Type CreateBackupStorageParamsType `json:"type"` + Url *string `json:"url,omitempty"` } // CreateBackupStorageParamsType defines model for CreateBackupStorageParams.Type. @@ -715,7 +721,10 @@ type UpdateBackupStorageParams struct { Description *string `json:"description,omitempty"` Region *string `json:"region,omitempty"` SecretKey *string `json:"secretKey,omitempty"` - Url *string `json:"url,omitempty"` + + // TargetNamespaces List of namespaces allowed to use this backup storage + TargetNamespaces *[]string `json:"targetNamespaces,omitempty"` + Url *string `json:"url,omitempty"` } // Version Everest version info @@ -5995,140 +6004,140 @@ func ParseVersionInfoResponse(rsp *http.Response) (*VersionInfoResponse, error) // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "//S/AQAA//+OeR6A7fUAAA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/docs/spec/openapi.yml b/docs/spec/openapi.yml index ef28f06a..3160b65a 100644 --- a/docs/spec/openapi.yml +++ b/docs/spec/openapi.yml @@ -1217,12 +1217,18 @@ components: region: type: string x-go-type-skip-optional-pointer: true + targetNamespaces: + type: array + description: List of namespaces allowed to use this backup storage + items: + type: string required: - name - bucketName - accessKey - secretKey - type + - targetNamespaces additionalProperties: false UpdateBackupStorageParams: type: object @@ -1241,6 +1247,11 @@ components: type: string region: type: string + targetNamespaces: + type: array + description: List of namespaces allowed to use this backup storage + items: + type: string additionalProperties: false BackupStorage: type: object @@ -1262,11 +1273,17 @@ components: region: type: string x-go-type-skip-optional-pointer: true + targetNamespaces: + type: array + description: List of namespaces allowed to use this backup storage + items: + type: string additionalProperties: false required: - name - bucketName - type + - targetNamespaces BackupStoragesList: type: array items: diff --git a/go.mod b/go.mod index bd4eb782..7ffa596f 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/labstack/echo/v4 v4.11.4 github.com/oapi-codegen/echo-middleware v1.0.1 github.com/oapi-codegen/runtime v1.1.1 - github.com/percona/everest-operator v0.6.0-dev1.0.20240202093727-ceb0bb0fb02f + github.com/percona/everest-operator v0.6.0-dev1.0.20240205163640-b47371dba0a5 github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.18.0 diff --git a/go.sum b/go.sum index b1e2c2d5..3075f959 100644 --- a/go.sum +++ b/go.sum @@ -420,8 +420,8 @@ github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8P github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/percona/everest-operator v0.6.0-dev1.0.20240202093727-ceb0bb0fb02f h1:ueUTTEw7Fc2yJyIq9pugBB8qai8LuO5uOBsuDMmJL70= -github.com/percona/everest-operator v0.6.0-dev1.0.20240202093727-ceb0bb0fb02f/go.mod h1:45pGpvWrPy495qiQqxNuOJor4wif+vTTTJP4Qee8qZk= +github.com/percona/everest-operator v0.6.0-dev1.0.20240205163640-b47371dba0a5 h1:qtLttjvVyc276YEZVdQ/aO8h+/M69Yyj5BcOnTBHY2M= +github.com/percona/everest-operator v0.6.0-dev1.0.20240205163640-b47371dba0a5/go.mod h1:45pGpvWrPy495qiQqxNuOJor4wif+vTTTJP4Qee8qZk= github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901 h1:BDgsZRCjEuxl2/z4yWBqB0s8d20shuIDks7/RVdZiLs= github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901/go.mod h1:fZRCMpUqkWlLVdRKqqaj001LoVP2eo6F0ZhoMPeXDng= github.com/percona/percona-postgresql-operator v0.0.0-20231220140959-ad5eef722609 h1:+UOK4gcHrRgqjo4smgfwT7/0apF6PhAJdQIdAV4ub/M= diff --git a/pkg/kubernetes/kubernetes.go b/pkg/kubernetes/kubernetes.go index 49204f11..35cb6c1e 100644 --- a/pkg/kubernetes/kubernetes.go +++ b/pkg/kubernetes/kubernetes.go @@ -48,8 +48,6 @@ const ( // EverestWatchNamespacesEnvVar is the name of the environment variable. EverestWatchNamespacesEnvVar = "WATCH_NAMESPACES" - - everestOperatorContainerName = "manager" ) // Kubernetes is a client for Kubernetes.