Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RepositoryServer CR update validation #2080

Merged
merged 7 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/apis/cr/v1alpha1/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// Package v1alpha1 is the v1alpha1 version of the API.
// +groupName=cr.kanister.io
// +versionName=v1alpha1
package v1alpha1

// While generating client files, we need code-generator package to be installed
Expand Down
16 changes: 14 additions & 2 deletions pkg/apis/cr/v1alpha1/repositoryserver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,26 @@ type RepositoryServerSpec struct {

// Storage references the backend store where a repository already exists
// and the credential necessary to connect to the backend store
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.secretRef) || has(self.secretRef)",message="secretRef field must not be allowed to be removed"
type Storage struct {
// SecretRef has the details of the object storage (location)
// where the kopia would backup the data
// +kubebuilder:validation:Optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
SecretRef corev1.SecretReference `json:"secretRef"`
// CredentialSecretRef stores the credentials required
// to connect to the object storage specified in `SecretRef` field
CredentialSecretRef corev1.SecretReference `json:"credentialSecretRef"`
}

// Repository has the details required by the repository server to connect to kopia repository
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.rootPath) || has(self.rootPath)",message="rootPath field must not be allowed to be removed"
type Repository struct {
// Path for the repository,it will be relative sub path
// Path for the repository, it will be a relative sub path
// within the path prefix specified in the location
// More info: https://kopia.io/docs/reference/command-line/common/#commands-to-manipulate-repository
// +kubebuilder:validation:Optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
RootPath string `json:"rootPath"`
// If specified, these values will be used by the controller to
// override default username when connecting to the
Expand All @@ -79,21 +85,27 @@ type Repository struct {
CacheSizeSettings CacheSizeSettings `json:"cacheSizeSettings,omitempty"`
}

// CacheSettings are the metadata/content cache size details
// CacheSizeSettings are the metadata/content cache size details
// that can be used while establishing connection to the kopia repository
type CacheSizeSettings struct {
Metadata string `json:"metadata"`
Content string `json:"content"`
}

// Server details required for starting the repository proxy server and initializing the repository client users
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.adminSecretRef) || has(self.adminSecretRef)",message="adminSecretRef field must not be allowed to be removed"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.tlsSecretRef) || has(self.tlsSecretRef)",message="tlsSecretRef field must not be allowed to be removed"
type Server struct {
UserAccess UserAccess `json:"userAccess"`
// AdminSecretRef has the username and password required to start the
// kopia repository server
// +kubebuilder:validation:Optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
AdminSecretRef corev1.SecretReference `json:"adminSecretRef"`
// TLSSecretRef has the certificates required for kopia repository
// client server connection
// +kubebuilder:validation:Optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
TLSSecretRef corev1.SecretReference `json:"tlsSecretRef"`
}

Expand Down
92 changes: 92 additions & 0 deletions pkg/apis/cr/v1alpha1/repositoryserver_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2023 The Kanister Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package v1alpha1

import (
"testing"

"github.com/pkg/errors"
. "gopkg.in/check.v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
)

const repoServerSpec = `
apiVersion: cr.kanister.io/v1alpha1
kind: RepositoryServer
metadata:
name: test-kopia-repo-server
namespace: kanister
spec:
storage:
secretRef:
name: test-s3-location
namespace: kanister
credentialSecretRef:
name: test-s3-creds
namespace: kanister
repository:
rootPath: /test-repo-controller/
passwordSecretRef:
name: test-repo-pass
namespace: kanister
username: test-repository-user
hostname: localhost
server:
adminSecretRef:
name: test-repository-admin-user
namespace: kanister
tlsSecretRef:
name: test-repository-server-tls-cert
namespace: kanister
userAccess:
userAccessSecretRef:
name: test-repository-server-user-access
namespace: kanister
username: test-kanister-user
`

func TestRepositoryServer(t *testing.T) { TestingT(t) }

func (s *TypesSuite) TestRepositoryServerDecode(c *C) {
rs, err := getRepositoryServerFromSpec([]byte(repoServerSpec))
c.Assert(err, IsNil)
c.Assert(rs, NotNil)
c.Assert(rs.Spec.Storage.SecretRef.Name, Equals, "test-s3-location")
c.Assert(rs.Spec.Storage.SecretRef.Namespace, Equals, "kanister")
c.Assert(rs.Spec.Storage.CredentialSecretRef.Name, Equals, "test-s3-creds")
c.Assert(rs.Spec.Storage.CredentialSecretRef.Namespace, Equals, "kanister")
c.Assert(rs.Spec.Repository.RootPath, Equals, "/test-repo-controller/")
c.Assert(rs.Spec.Repository.PasswordSecretRef.Name, Equals, "test-repo-pass")
c.Assert(rs.Spec.Repository.PasswordSecretRef.Namespace, Equals, "kanister")
c.Assert(rs.Spec.Repository.Username, Equals, "test-repository-user")
c.Assert(rs.Spec.Repository.Hostname, Equals, "localhost")
c.Assert(rs.Spec.Server.AdminSecretRef.Name, Equals, "test-repository-admin-user")
c.Assert(rs.Spec.Server.AdminSecretRef.Namespace, Equals, "kanister")
c.Assert(rs.Spec.Server.TLSSecretRef.Name, Equals, "test-repository-server-tls-cert")
c.Assert(rs.Spec.Server.TLSSecretRef.Namespace, Equals, "kanister")
c.Assert(rs.Spec.Server.UserAccess.UserAccessSecretRef.Name, Equals, "test-repository-server-user-access")
c.Assert(rs.Spec.Server.UserAccess.UserAccessSecretRef.Namespace, Equals, "kanister")
c.Assert(rs.Spec.Server.UserAccess.Username, Equals, "test-kanister-user")
}

func getRepositoryServerFromSpec(spec []byte) (*RepositoryServer, error) {
repositoryServer := &RepositoryServer{}
d := serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer()
if _, _, err := d.Decode([]byte(spec), nil, repositoryServer); err != nil {
return nil, errors.Wrap(err, "Failed to decode RepositoryServer")
}
return repositoryServer, nil
}
Loading