Skip to content

Commit 4148243

Browse files
AlexsJonesthschue
andauthored
adds validation of the json schema (#27)
* adds validation of the json schema * Update mutating_admission_webhook.go * Update validating_admission_webhoook.go * reworked to use FF CR as the webhook trigger * reworked to use FF CR as the webhook trigger * removed kustomize change * removed kustomize change * Update main.go Co-authored-by: Thomas Schuetz <[email protected]>
1 parent 1dec80d commit 4148243

15 files changed

+318
-105
lines changed

PROJECT

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,6 @@ resources:
1212
domain: openfeature.dev
1313
group: core
1414
kind: FeatureFlagConfiguration
15-
path: github.com/open-feature/open-feature-operator/api/v1alpha1
15+
path: github.com/open-feature/open-feature-operator/apis/core/v1alpha1
1616
version: v1alpha1
17-
- api:
18-
crdVersion: v1
19-
namespaced: true
20-
controller: true
21-
domain: openfeature.dev
22-
group: core
23-
kind: Deployment
24-
path: github.com/open-feature/open-feature-operator/api/v1alpha1
25-
version: v1alpha1
26-
webhooks:
27-
defaulting: true
28-
validation: true
29-
webhookVersion: v1
30-
- group: apps
31-
kind: Deployment
32-
path: k8s.io/api/apps/v1
33-
version: v1
34-
webhooks:
35-
defaulting: true
36-
validation: true
37-
webhookVersion: v1
3817
version: "3"

apis/core/v1alpha1/featureflagconfiguration_types.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package v1alpha1
1818

1919
import (
20+
"github.com/open-feature/open-feature-operator/pkg/utils"
21+
corev1 "k8s.io/api/core/v1"
2022
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2123
)
2224

@@ -62,3 +64,29 @@ type FeatureFlagConfigurationList struct {
6264
func init() {
6365
SchemeBuilder.Register(&FeatureFlagConfiguration{}, &FeatureFlagConfigurationList{})
6466
}
67+
68+
func GetFfReference(ff *FeatureFlagConfiguration) metav1.OwnerReference {
69+
return metav1.OwnerReference{
70+
APIVersion: ff.APIVersion,
71+
Kind: ff.Kind,
72+
Name: ff.Name,
73+
UID: ff.UID,
74+
Controller: utils.TrueVal(),
75+
}
76+
}
77+
78+
func GenerateFfConfigMap(name string, namespace string, references []metav1.OwnerReference, spec FeatureFlagConfigurationSpec) corev1.ConfigMap {
79+
return corev1.ConfigMap{
80+
ObjectMeta: metav1.ObjectMeta{
81+
Name: name,
82+
Namespace: namespace,
83+
Annotations: map[string]string{
84+
"openfeature.dev/featureflagconfiguration": name,
85+
},
86+
OwnerReferences: references,
87+
},
88+
Data: map[string]string{
89+
"config.yaml": spec.FeatureFlagSpec,
90+
},
91+
}
92+
}

apis/core/v1alpha1/zz_generated.deepcopy.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/samples/config_v1alpha1_featureflagconfiguration.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@ metadata:
44
name: featureflagconfiguration-sample
55
spec:
66
featureFlagSpec: |
7-
{
8-
"foo" : "bar"
9-
}
7+
{}

config/samples/deployment-2.yaml

Lines changed: 0 additions & 22 deletions
This file was deleted.

config/samples/deployment.yaml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,27 @@ spec:
1919
- name: nginx
2020
image: nginx:1.14.2
2121
ports:
22-
- containerPort: 80
22+
- containerPort: 80
23+
---
24+
apiVersion: apps/v1
25+
kind: Deployment
26+
metadata:
27+
name: nginx-deployment-2
28+
spec:
29+
selector:
30+
matchLabels:
31+
app: nginx
32+
replicas: 5 # tells deployment to run 2 pods matching the template
33+
template:
34+
metadata:
35+
labels:
36+
app: nginx
37+
annotations:
38+
openfeature.dev: "enabled"
39+
openfeature.dev/featureflagconfiguration: "featureflagconfiguration-sample"
40+
spec:
41+
containers:
42+
- name: nginx
43+
image: nginx:1.14.2
44+
ports:
45+
- containerPort: 80

config/webhook/manifests.yaml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ webhooks:
1313
namespace: system
1414
path: /mutate-v1-pod
1515
failurePolicy: Ignore
16-
name: mpod.kb.io
16+
name: mutate.openfeature.dev
1717
rules:
1818
- apiGroups:
1919
- ""
@@ -25,3 +25,30 @@ webhooks:
2525
resources:
2626
- pods
2727
sideEffects: NoneOnDryRun
28+
---
29+
apiVersion: admissionregistration.k8s.io/v1
30+
kind: ValidatingWebhookConfiguration
31+
metadata:
32+
creationTimestamp: null
33+
name: validating-webhook-configuration
34+
webhooks:
35+
- admissionReviewVersions:
36+
- v1
37+
clientConfig:
38+
service:
39+
name: webhook-service
40+
namespace: system
41+
path: /validate-v1alpha1-featureflagconfiguration
42+
failurePolicy: Fail
43+
name: validate.featureflagconfiguration.openfeature.dev
44+
rules:
45+
- apiGroups:
46+
- core.openfeature.dev
47+
apiVersions:
48+
- v1alpha1
49+
operations:
50+
- CREATE
51+
- UPDATE
52+
resources:
53+
- featureflagconfigurations
54+
sideEffects: None

controllers/featureflagconfiguration_controller.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,22 @@ package controllers
1818

1919
import (
2020
"context"
21+
"time"
22+
2123
"github.com/go-logr/logr"
2224
"github.com/open-feature/open-feature-operator/pkg/utils"
2325
corev1 "k8s.io/api/core/v1"
2426
"k8s.io/apimachinery/pkg/api/errors"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
"k8s.io/client-go/tools/record"
2729
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
28-
"time"
2930

3031
"k8s.io/apimachinery/pkg/runtime"
3132
ctrl "sigs.k8s.io/controller-runtime"
3233
"sigs.k8s.io/controller-runtime/pkg/client"
3334
"sigs.k8s.io/controller-runtime/pkg/log"
3435

35-
configv1alpha1 "github.com/open-feature/open-feature-operator/apis/core/v1alpha1"
36+
corev1alpha1 "github.com/open-feature/open-feature-operator/apis/core/v1alpha1"
3637
)
3738

3839
// FeatureFlagConfigurationReconciler reconciles a FeatureFlagConfiguration object
@@ -70,7 +71,7 @@ func (r *FeatureFlagConfigurationReconciler) Reconcile(ctx context.Context, req
7071
r.Log = log.FromContext(ctx)
7172
r.Log.Info("Reconciling" + crdName)
7273

73-
ffconf := &configv1alpha1.FeatureFlagConfiguration{}
74+
ffconf := &corev1alpha1.FeatureFlagConfiguration{}
7475
if err := r.Client.Get(ctx, req.NamespacedName, ffconf); err != nil {
7576
if errors.IsNotFound(err) {
7677
// taking down all associated K8s resources is handled by K8s
@@ -124,7 +125,7 @@ func (r *FeatureFlagConfigurationReconciler) Reconcile(ctx context.Context, req
124125
// Append OwnerReference if not set
125126
if !r.featureFlagResourceIsOwner(ffconf, cm) {
126127
r.Log.Info("Setting owner reference for " + cm.Name)
127-
cm.OwnerReferences = append(cm.OwnerReferences, utils.GetFfReference(ffconf))
128+
cm.OwnerReferences = append(cm.OwnerReferences, corev1alpha1.GetFfReference(ffconf))
128129
err := r.Client.Update(ctx, &cm)
129130
if err != nil {
130131
return r.finishReconcile(err, true)
@@ -138,7 +139,7 @@ func (r *FeatureFlagConfigurationReconciler) Reconcile(ctx context.Context, req
138139
// Update ConfigMap Spec
139140
r.Log.Info("Updating ConfigMap Spec " + cm.Name)
140141
cm.Data = map[string]string{
141-
"config.yaml": ffconf.Spec.FeatureFlagSpec,
142+
"config.json": ffconf.Spec.FeatureFlagSpec,
142143
}
143144
err := r.Client.Update(ctx, &cm)
144145
if err != nil {
@@ -148,9 +149,9 @@ func (r *FeatureFlagConfigurationReconciler) Reconcile(ctx context.Context, req
148149

149150
if !cmExists {
150151
ffOwnerRefs := []metav1.OwnerReference{
151-
utils.GetFfReference(ffconf),
152+
corev1alpha1.GetFfReference(ffconf),
152153
}
153-
cm := utils.GenerateFfConfigMap(ffconf.Name, ffconf.Namespace, ffOwnerRefs, ffconf.Spec)
154+
cm := corev1alpha1.GenerateFfConfigMap(ffconf.Name, ffconf.Namespace, ffOwnerRefs, ffconf.Spec)
154155

155156
podList := &corev1.PodList{}
156157
if err := r.List(ctx, podList); err != nil {
@@ -178,7 +179,7 @@ func (r *FeatureFlagConfigurationReconciler) Reconcile(ctx context.Context, req
178179
// SetupWithManager sets up the controller with the Manager.
179180
func (r *FeatureFlagConfigurationReconciler) SetupWithManager(mgr ctrl.Manager) error {
180181
return ctrl.NewControllerManagedBy(mgr).
181-
For(&configv1alpha1.FeatureFlagConfiguration{}).
182+
For(&corev1alpha1.FeatureFlagConfiguration{}).
182183
Owns(&corev1.ConfigMap{}).
183184
Complete(r)
184185
}
@@ -200,9 +201,9 @@ func (r *FeatureFlagConfigurationReconciler) finishReconcile(err error, requeueI
200201
return ctrl.Result{Requeue: true, RequeueAfter: interval}, nil
201202
}
202203

203-
func (r *FeatureFlagConfigurationReconciler) featureFlagResourceIsOwner(ff *configv1alpha1.FeatureFlagConfiguration, cm corev1.ConfigMap) bool {
204+
func (r *FeatureFlagConfigurationReconciler) featureFlagResourceIsOwner(ff *corev1alpha1.FeatureFlagConfiguration, cm corev1.ConfigMap) bool {
204205
for _, cmOwner := range cm.OwnerReferences {
205-
if cmOwner.UID == utils.GetFfReference(ff).UID {
206+
if cmOwner.UID == corev1alpha1.GetFfReference(ff).UID {
206207
return true
207208
}
208209
}

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/go-logr/logr v1.2.0
77
github.com/onsi/ginkgo v1.16.5
88
github.com/onsi/gomega v1.17.0
9+
github.com/xeipuuv/gojsonschema v1.2.0
910
k8s.io/api v0.23.0
1011
k8s.io/apimachinery v0.23.0
1112
k8s.io/client-go v0.23.0
@@ -47,6 +48,8 @@ require (
4748
github.com/prometheus/procfs v0.6.0 // indirect
4849
github.com/spf13/pflag v1.0.5 // indirect
4950
github.com/stretchr/testify v1.7.1 // indirect
51+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
52+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
5053
go.uber.org/atomic v1.7.0 // indirect
5154
go.uber.org/multierr v1.6.0 // indirect
5255
go.uber.org/zap v1.19.1 // indirect
@@ -73,4 +76,4 @@ require (
7376
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
7477
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
7578
sigs.k8s.io/yaml v1.3.0 // indirect
76-
)
79+
)

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
478478
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
479479
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
480480
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
481+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
482+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
483+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
484+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
485+
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
486+
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
481487
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
482488
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
483489
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

0 commit comments

Comments
 (0)