Skip to content

Commit

Permalink
Add CR validation webhook (#53)
Browse files Browse the repository at this point in the history
* Add CR validation webhook

In addition, added template rendering frequency per CR

* remove suite test

* allow remove CR with non-existing app

* Migrate the validation engine from admission controller to the reconcile
loop

The purpose is to validate the rendered text, not the template.

* Add metadataInjector CR

Add unit tests also

* update controller-runtime version from 0.8.1 to 0.8.2

* update-docs
  • Loading branch information
cuttingedge1109 authored Mar 24, 2021
1 parent 6d0cddb commit fb35725
Show file tree
Hide file tree
Showing 37 changed files with 1,149 additions and 53 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,7 @@ tags
!.vscode/extensions.json
.history

# GoLand
.idea/

# End of https://www.gitignore.io/api/go,vim,emacs,visualstudiocode
4 changes: 4 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ resources:
group: konfigurator
kind: KonfiguratorTemplate
version: v1alpha1
- crdVersion: v1
group: konfigurator
kind: PodMetadataInjector
version: v1alpha1
version: 3-alpha
plugins:
manifests.sdk.operatorframework.io/v2: {}
Expand Down
21 changes: 1 addition & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,7 @@ Deploying Konfigurator requires:
1. Deploying CRD to your cluster
2. Deploying Konfigurator operator

You can deploy the CRD and operator on your kubernetes cluster via any of the following methods.

### Vanilla Manifests

You can apply vanilla manifests by running the following command

```bash
kubectl apply -f https://raw.githubusercontent.com/stakater/Konfigurator/master/deployments/kubernetes/konfigurator.yaml
```

Konfigurator by default looks for **KonfiguratorTemplate** only in the namespace where it is deployed, but it can be managed to work globally, you would have to change the `WATCH_NAMESPACE` environment variable to "" in the above manifest. e.g. change `WATCH_NAMESPACE` section to:

```yaml
- name: WATCH_NAMESPACE
value: ""
```
### Helm Charts
Alternatively if you have configured helm on your cluster, you can add konfigurator to helm from our public chart repository and deploy it via helm using below mentioned commands
You can deploy CRDs either together or separately with the operator in the helm chart by setting `konfigurator.deployCRD` in values.yaml file.

```bash
helm repo add stakater https://stakater.github.io/stakater-charts
Expand Down
5 changes: 4 additions & 1 deletion api/v1alpha1/konfiguratortemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@ type VolumeMount struct {

// KonfiguratorTemplateSpec defines the desired state of KonfiguratorTemplate
type KonfiguratorTemplateSpec struct {
App App `json:"app"`
RenderTarget RenderTarget `json:"renderTarget"`
Templates map[string]string `json:"templates"`
App App `json:"app"`
// Rendering frequency in minutes
UpdateFrequency int `json:"updateFrequency,omitempty"`
ValidationWebhookURL string `json:"validationWebhookURL,omitempty"`
}

// KonfiguratorTemplateStatus defines the observed state of KonfiguratorTemplate
Expand Down
61 changes: 61 additions & 0 deletions api/v1alpha1/podmetadatainjector_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
Copyright 2021.
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"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// PodMetadataInjectorSpec defines the desired state of PodMetadataInjector
type PodMetadataInjectorSpec struct {
Selector *metav1.LabelSelector `json:"selector"`
ObjectMeta metav1.ObjectMeta `json:"objectMeta"`
}

// PodMetadataInjectorStatus defines the observed state of PodMetadataInjector
type PodMetadataInjectorStatus 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

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

Spec PodMetadataInjectorSpec `json:"spec,omitempty"`
Status PodMetadataInjectorStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

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

func init() {
SchemeBuilder.Register(&PodMetadataInjector{}, &PodMetadataInjectorList{})
}
98 changes: 97 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions charts/konfigurator/templates/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,18 @@ spec:
singular: konfiguratortemplate
scope: Namespaced
version: v1alpha1
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: podmetadatainjectors.konfigurator.stakater.com
spec:
group: konfigurator.stakater.com
names:
kind: PodMetadataInjector
listKind: PodMetadataInjectorList
plural: podmetadatainjectors
singular: podmetadatainjector
scope: Namespaced
version: v1alpha1
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ spec:
additionalProperties:
type: string
type: object
updateFrequency:
description: Rendering frequency in minutes
type: integer
validationWebhookURL:
type: string
required:
- app
- renderTarget
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.5.0
creationTimestamp: null
name: podmetadatainjectors.konfigurator.stakater.com
spec:
group: konfigurator.stakater.com
names:
kind: PodMetadataInjector
listKind: PodMetadataInjectorList
plural: podmetadatainjectors
singular: podmetadatainjector
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: PodMetadataInjector is the Schema for the podmetadatainjectors API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: PodMetadataInjectorSpec defines the desired state of PodMetadataInjector
properties:
objectMeta:
type: object
selector:
description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
items:
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
properties:
key:
description: key is the label key that the selector applies to.
type: string
operator:
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
required:
- objectMeta
- selector
type: object
status:
description: PodMetadataInjectorStatus defines the observed state of PodMetadataInjector
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
5 changes: 4 additions & 1 deletion config/crd/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
# It should be run by config/default
resources:
- bases/konfigurator.stakater.com_konfiguratortemplates.yaml
- bases/konfigurator.stakater.com_podmetadatainjectors.yaml
# +kubebuilder:scaffold:crdkustomizeresource

patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_konfiguratortemplates.yaml
#- patches/webhook_in_podmetadatainjectors.yaml
# +kubebuilder:scaffold:crdkustomizewebhookpatch

# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_konfiguratortemplates.yaml
# - patches/cainjection_in_konfiguratortemplates.yaml
#- patches/cainjection_in_podmetadatainjectors.yaml
# +kubebuilder:scaffold:crdkustomizecainjectionpatch

# the following config is for teaching kustomize how to do kustomization for CRDs.
Expand Down
7 changes: 7 additions & 0 deletions config/crd/patches/cainjection_in_metadatainjections.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# The following patch adds a directive for certmanager to inject CA into the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
name: podmetadatainjectors.konfigurator.stakater.com
Loading

0 comments on commit fb35725

Please sign in to comment.