Skip to content

Commit

Permalink
✨ New Library CRD (#203)
Browse files Browse the repository at this point in the history
Added new Library CRD with controller. This makes it possible to deploy
Library resources and the controller will create an equivalent Library
in Styra.

Also fixed flaky tests
  • Loading branch information
bdumpp committed Nov 8, 2023
1 parent 903dfc9 commit 7108689
Show file tree
Hide file tree
Showing 29 changed files with 2,669 additions and 148 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,15 @@ lint: golangci-lint ## Run linters

.PHONY: test
test: ginkgo manifests generate lint envtest generate-mocks ## Run all tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) -r --coverprofile cover.out
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) -r -p --output-interceptor-mode=none

.PHONY: test-unit
test-unit: ginkgo manifests generate lint generate-mocks ## Run unit tests.
$(GINKGO) -r --label-filter "!integration" --coverprofile cover.out
$(GINKGO) -r --label-filter "!integration" --output-interceptor-mode=none

.PHONY: test-integration ## Run integration tests.
test-integration: ginkgo manifests generate lint envtest generate-mocks ## Run integration tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) -r --label-filter "integration" --coverprofile cover.out
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" $(GINKGO) -r -p --label-filter "integration" --output-interceptor-mode=none

.PHONY: kind-create
kind-create: kind ## Create kind cluster
Expand Down
13 changes: 13 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,17 @@ resources:
kind: ProjectConfig
path: github.com/bankdata/styra-controller/api/config/v2alpha2
version: v2alpha2
- api:
crdVersion: v1
namespaced: true
controller: true
domain: bankdata.dk
group: styra
kind: Library
path: github.com/bankdata/styra-controller/api/styra/v1alpha1
version: v1alpha1
webhooks:
defaulting: true
validation: true
webhookVersion: v1
version: "3"
140 changes: 140 additions & 0 deletions api/styra/v1alpha1/library_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
Copyright (C) 2023 Bankdata ([email protected])
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// LibrarySpec defines the desired state of Library
type LibrarySpec struct {

// Name is the name the Library will have in Styra DAS
Name string `json:"name"`

// Description is the description of the Library
Description string `json:"description"`

// Subjects is the list of subjects which should have access to the system.
Subjects []LibrarySubject `json:"subjects,omitempty"`

// SourceControl is the sourcecontrol configuration for the Library
SourceControl *SourceControl `json:"sourceControl"`

// Datasources is the list of datasources in the Library
Datasources []LibraryDatasource `json:"datasources,omitempty"`
}

// LibraryDatasource contains metadata of a datasource, stored in a library
type LibraryDatasource struct {
// Path is the path within the system where the datasource should reside.
Path string `json:"path"`

// Description is a description of the datasource
Description string `json:"description,omitempty"`
}

// SourceControl is a struct from styra where we only use a single field
// but kept for clarity when comparing to the API
type SourceControl struct {
LibraryOrigin *GitRepo `json:"libraryOrigin"`
}

// LibrarySubjectKind represents a kind of a subject.
type LibrarySubjectKind string

const (
// LibrarySubjectKindUser is the subject kind user.
LibrarySubjectKindUser LibrarySubjectKind = "user"

// LibrarySubjectKindGroup is the subject kind group.
LibrarySubjectKindGroup LibrarySubjectKind = "group"
)

// LibrarySubject represents a subject which has been granted access to the Library.
// The subject is assigned to the LibraryViewer role.
type LibrarySubject struct {
// Kind is the LibrarySubjectKind of the subject.
//+kubebuilder:validation:Enum=user;group
Kind LibrarySubjectKind `json:"kind,omitempty"`

// Name is the name of the subject. The meaning of this field depends on the
// SubjectKind.
Name string `json:"name"`
}

// IsUser returns whether or not the kind of the subject is a user.
func (subject LibrarySubject) IsUser() bool {
return subject.Kind == LibrarySubjectKindUser || subject.Kind == ""
}

// GitRepo defines the Git configurations a library can be defined by
type GitRepo struct {
// Path is the path in the git repo where the policies are located.
Path string `json:"path,omitempty"`

// Reference is used to point to a tag or branch. This will be ignored if
// `Commit` is specified.
Reference string `json:"reference,omitempty"`

// Commit is used to point to a specific commit SHA. This takes precedence
// over `Reference` if both are specified.
Commit string `json:"commit,omitempty"`

// URL is the URL of the git repo.
URL string `json:"url"`
}

// LibrarySecretRef defines how to access a k8s secret for the library.
type LibrarySecretRef struct {
// Namespace is the namespace where the secret resides.
Namespace string `json:"namespace"`
// Name is the name of the secret.
Name string `json:"name"`
}

// LibraryStatus defines the observed state of Library
type LibraryStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Cluster

// Library is the Schema for the libraries API
type Library struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec LibrarySpec `json:"spec,omitempty"`
Status LibraryStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// LibraryList contains a list of Library
type LibraryList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Library `json:"items"`
}

func init() {
SchemeBuilder.Register(&Library{}, &LibraryList{})
}
79 changes: 79 additions & 0 deletions api/styra/v1alpha1/library_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
Copyright (C) 2023 Bankdata ([email protected])
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 (
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

// log is for logging in this package.
var librarylog = logf.Log.WithName("library-resource")

// SetupWebhookWithManager sets up the Library webhooks with the Manager.
func (r *Library) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
}

// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!

//+kubebuilder:webhook:path=/mutate-styra-bankdata-dk-v1alpha1-library,mutating=true,failurePolicy=fail,sideEffects=None,groups=styra.bankdata.dk,resources=libraries,verbs=create;update,versions=v1alpha1,name=mlibrary.kb.io,admissionReviewVersions=v1

var _ webhook.Defaulter = &Library{}

// Default implements webhook.Defaulter so a webhook will be registered for the type
func (r *Library) Default() {
librarylog.Info("default", "name", r.Name)

if r.Spec.SourceControl.LibraryOrigin.Commit != "" && r.Spec.SourceControl.LibraryOrigin.Reference != "" {
r.Spec.SourceControl.LibraryOrigin.Reference = ""
}
}

// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
//+kubebuilder:webhook:path=/validate-styra-bankdata-dk-v1alpha1-library,mutating=false,failurePolicy=fail,sideEffects=None,groups=styra.bankdata.dk,resources=libraries,verbs=create;update,versions=v1alpha1,name=vlibrary.kb.io,admissionReviewVersions=v1

var _ webhook.Validator = &Library{}

// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (r *Library) ValidateCreate() (admission.Warnings, error) {
librarylog.Info("validate create", "name", r.Name)

// TODO(user): fill in your validation logic upon object creation.
return nil, nil
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (r *Library) ValidateUpdate(_ runtime.Object) (admission.Warnings, error) {
librarylog.Info("validate update", "name", r.Name)

// TODO(user): fill in your validation logic upon object update.
return nil, nil
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *Library) ValidateDelete() (admission.Warnings, error) {
librarylog.Info("validate delete", "name", r.Name)

// TODO(user): fill in your validation logic upon object deletion.
return nil, nil
}
Loading

0 comments on commit 7108689

Please sign in to comment.