Skip to content

Commit 675724a

Browse files
authored
Merge pull request #207 from skyerus/issue-72_crd-structure
feat: structured the featureflagconfiguration CRD
2 parents 28c8f36 + e2f73e0 commit 675724a

19 files changed

+923
-90
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ KUSTOMIZE_OVERLAY ?= DEFAULT
66
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
77
FLAGD_VERSION=v0.2.5
88
CHART_VERSION=v0.2.18# x-release-please-version
9-
ENVTEST_K8S_VERSION = 1.23
9+
ENVTEST_K8S_VERSION = 1.25
1010

1111
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
1212
ifeq (,$(shell go env GOBIN))
@@ -147,7 +147,7 @@ ENVTEST ?= $(LOCALBIN)/setup-envtest
147147

148148
## Tool Versions
149149
KUSTOMIZE_VERSION ?= v4.5.7
150-
CONTROLLER_TOOLS_VERSION ?= v0.8.0
150+
CONTROLLER_TOOLS_VERSION ?= v0.10.0
151151

152152
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
153153
.PHONY: kustomize

PROJECT

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,15 @@ resources:
1414
kind: FeatureFlagConfiguration
1515
path: github.com/open-feature/open-feature-operator/apis/core/v1alpha1
1616
version: v1alpha1
17+
webhooks:
18+
conversion: true
19+
webhookVersion: v1
20+
- api:
21+
crdVersion: v1
22+
namespaced: true
23+
domain: openfeature.dev
24+
group: core
25+
kind: FeatureFlagConfiguration
26+
path: github.com/open-feature/open-feature-operator/apis/core/v1alpha2
27+
version: v1alpha2
1728
version: "3"

README.md

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,20 @@ When wishing to leverage feature flagging within the local pod, the following st
107107
_See [here](config/samples/crds/custom_provider.yaml) for additional custom resource parameters_
108108

109109
```
110-
apiVersion: core.openfeature.dev/v1alpha1
110+
apiVersion: core.openfeature.dev/v1alpha2
111111
kind: FeatureFlagConfiguration
112112
metadata:
113113
name: featureflagconfiguration-sample
114114
spec:
115-
featureFlagSpec: |
116-
{
117-
"flags": {
118-
"foo": {
119-
"state": "ENABLED",
120-
"variants": {
121-
"bar": "BAR",
122-
"baz": "BAZ"
123-
},
124-
"defaultVariant": "bar",
125-
"targeting": {}
126-
}
127-
}
128-
}
115+
featureFlagSpec:
116+
flags:
117+
foo:
118+
state: "ENABLED"
119+
variants:
120+
"bar": "BAR"
121+
"baz": "BAZ"
122+
defaultVariant: "bar",
123+
targeting: {}
129124
```
130125

131126
1. Reference the CR within the pod spec annotations
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2022.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import ctrl "sigs.k8s.io/controller-runtime"
20+
21+
// Hub marks this type as a conversion hub.
22+
func (ffc *FeatureFlagConfiguration) Hub() {}
23+
24+
func (r *FeatureFlagConfiguration) SetupWebhookWithManager(mgr ctrl.Manager) error {
25+
return ctrl.NewWebhookManagedBy(mgr).
26+
For(r).
27+
Complete()
28+
}

apis/core/v1alpha1/featureflagconfiguration_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ type FeatureFlagConfigurationStatus struct {
7373

7474
//+kubebuilder:object:root=true
7575
//+kubebuilder:subresource:status
76+
//+kubebuilder:storageversion
7677

7778
// FeatureFlagConfiguration is the Schema for the featureflagconfigurations API
7879
type FeatureFlagConfiguration struct {
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
Copyright 2022.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha2
18+
19+
import (
20+
"encoding/json"
21+
"fmt"
22+
"github.com/open-feature/open-feature-operator/apis/core/v1alpha1"
23+
ctrl "sigs.k8s.io/controller-runtime"
24+
"sigs.k8s.io/controller-runtime/pkg/conversion"
25+
)
26+
27+
func (ffc *FeatureFlagConfiguration) SetupWebhookWithManager(mgr ctrl.Manager) error {
28+
return ctrl.NewWebhookManagedBy(mgr).
29+
For(ffc).
30+
Complete()
31+
}
32+
33+
func (src *FeatureFlagConfiguration) ConvertTo(dstRaw conversion.Hub) error {
34+
dst := dstRaw.(*v1alpha1.FeatureFlagConfiguration)
35+
36+
dst.ObjectMeta = src.ObjectMeta
37+
if src.Spec.ServiceProvider != nil {
38+
dst.Spec.ServiceProvider = &v1alpha1.FeatureFlagServiceProvider{
39+
Name: src.Spec.ServiceProvider.Name,
40+
Credentials: src.Spec.ServiceProvider.Credentials,
41+
}
42+
}
43+
44+
if src.Spec.SyncProvider != nil {
45+
dst.Spec.SyncProvider = &v1alpha1.FeatureFlagSyncProvider{Name: src.Spec.SyncProvider.Name}
46+
}
47+
48+
if src.Spec.FlagDSpec != nil {
49+
dst.Spec.FlagDSpec = &v1alpha1.FlagDSpec{Envs: src.Spec.FlagDSpec.Envs}
50+
}
51+
52+
featureFlagSpecB, err := json.Marshal(src.Spec.FeatureFlagSpec)
53+
if err != nil {
54+
return fmt.Errorf("featureflagspec: %w", err)
55+
}
56+
57+
dst.Spec.FeatureFlagSpec = string(featureFlagSpecB)
58+
59+
return nil
60+
}
61+
62+
func (dst *FeatureFlagConfiguration) ConvertFrom(srcRaw conversion.Hub) error {
63+
src := srcRaw.(*v1alpha1.FeatureFlagConfiguration)
64+
65+
dst.ObjectMeta = src.ObjectMeta
66+
if src.Spec.ServiceProvider != nil {
67+
dst.Spec.ServiceProvider = &FeatureFlagServiceProvider{
68+
Name: src.Spec.ServiceProvider.Name,
69+
Credentials: src.Spec.ServiceProvider.Credentials,
70+
}
71+
}
72+
73+
if src.Spec.SyncProvider != nil {
74+
dst.Spec.SyncProvider = &FeatureFlagSyncProvider{Name: src.Spec.SyncProvider.Name}
75+
}
76+
77+
if src.Spec.FlagDSpec != nil {
78+
dst.Spec.FlagDSpec = &FlagDSpec{Envs: src.Spec.FlagDSpec.Envs}
79+
}
80+
81+
var featureFlagSpec FeatureFlagSpec
82+
if err := json.Unmarshal([]byte(src.Spec.FeatureFlagSpec), &featureFlagSpec); err != nil {
83+
return fmt.Errorf("featureflagspec: %w", err)
84+
}
85+
86+
dst.Spec.FeatureFlagSpec = featureFlagSpec
87+
88+
return nil
89+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
Copyright 2022.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha2
18+
19+
import (
20+
"encoding/json"
21+
"github.com/open-feature/open-feature-operator/pkg/utils"
22+
corev1 "k8s.io/api/core/v1"
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
)
25+
26+
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
27+
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
28+
29+
// FeatureFlagConfigurationSpec defines the desired state of FeatureFlagConfiguration
30+
type FeatureFlagConfigurationSpec struct {
31+
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
32+
// Important: Run "make" to regenerate code after modifying this file
33+
// +optional
34+
// +nullable
35+
ServiceProvider *FeatureFlagServiceProvider `json:"serviceProvider"`
36+
// +optional
37+
// +nullable
38+
SyncProvider *FeatureFlagSyncProvider `json:"syncProvider"`
39+
// +optional
40+
// +nullable
41+
FlagDSpec *FlagDSpec `json:"flagDSpec"`
42+
// FeatureFlagSpec is the structured representation of the feature flag specification
43+
FeatureFlagSpec FeatureFlagSpec `json:"featureFlagSpec,omitempty"`
44+
}
45+
46+
type FlagDSpec struct {
47+
// +optional
48+
Envs []corev1.EnvVar `json:"envs"`
49+
}
50+
51+
type FeatureFlagSpec struct {
52+
Flags map[string]FlagSpec `json:"flags"`
53+
// +optional
54+
// +kubebuilder:validation:Schemaless
55+
// +kubebuilder:pruning:PreserveUnknownFields
56+
// +kubebuilder:validation:Type=object
57+
Evaluators json.RawMessage `json:"$evaluators,omitempty"`
58+
}
59+
60+
type FlagSpec struct {
61+
// +kubebuilder:validation:Enum=ENABLED;DISABLED
62+
State string `json:"state"`
63+
// +kubebuilder:validation:Schemaless
64+
// +kubebuilder:pruning:PreserveUnknownFields
65+
// +kubebuilder:validation:Type=object
66+
Variants json.RawMessage `json:"variants"`
67+
DefaultVariant string `json:"defaultVariant"`
68+
// +optional
69+
// +kubebuilder:validation:Schemaless
70+
// +kubebuilder:pruning:PreserveUnknownFields
71+
// +kubebuilder:validation:Type=object
72+
// Targeting is the json targeting rule
73+
Targeting json.RawMessage `json:"targeting,omitempty"`
74+
}
75+
76+
type FeatureFlagSyncProvider struct {
77+
Name string `json:"name"`
78+
}
79+
80+
func (ffsp FeatureFlagSyncProvider) IsKubernetes() bool {
81+
return ffsp.Name == "kubernetes"
82+
}
83+
84+
type FeatureFlagServiceProvider struct {
85+
// +kubebuilder:validation:Enum=flagd
86+
Name string `json:"name"`
87+
// +optional
88+
// +nullable
89+
Credentials *corev1.ObjectReference `json:"credentials"`
90+
}
91+
92+
// FeatureFlagConfigurationStatus defines the observed state of FeatureFlagConfiguration
93+
type FeatureFlagConfigurationStatus struct {
94+
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
95+
// Important: Run "make" to regenerate code after modifying this file
96+
}
97+
98+
//+kubebuilder:object:root=true
99+
//+kubebuilder:subresource:status
100+
101+
// FeatureFlagConfiguration is the Schema for the featureflagconfigurations API
102+
type FeatureFlagConfiguration struct {
103+
metav1.TypeMeta `json:",inline"`
104+
metav1.ObjectMeta `json:"metadata,omitempty"`
105+
106+
Spec FeatureFlagConfigurationSpec `json:"spec,omitempty"`
107+
Status FeatureFlagConfigurationStatus `json:"status,omitempty"`
108+
}
109+
110+
//+kubebuilder:object:root=true
111+
112+
// FeatureFlagConfigurationList contains a list of FeatureFlagConfiguration
113+
type FeatureFlagConfigurationList struct {
114+
metav1.TypeMeta `json:",inline"`
115+
metav1.ListMeta `json:"metadata,omitempty"`
116+
Items []FeatureFlagConfiguration `json:"items"`
117+
}
118+
119+
func init() {
120+
SchemeBuilder.Register(&FeatureFlagConfiguration{}, &FeatureFlagConfigurationList{})
121+
}
122+
123+
func GetFfReference(ff *FeatureFlagConfiguration) metav1.OwnerReference {
124+
return metav1.OwnerReference{
125+
APIVersion: ff.APIVersion,
126+
Kind: ff.Kind,
127+
Name: ff.Name,
128+
UID: ff.UID,
129+
Controller: utils.TrueVal(),
130+
}
131+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright 2022.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package v1alpha2 contains API Schema definitions for the core v1alpha2 API group
18+
// +kubebuilder:object:generate=true
19+
// +groupName=core.openfeature.dev
20+
package v1alpha2
21+
22+
import (
23+
"k8s.io/apimachinery/pkg/runtime/schema"
24+
"sigs.k8s.io/controller-runtime/pkg/scheme"
25+
)
26+
27+
var (
28+
// GroupVersion is group version used to register these objects
29+
GroupVersion = schema.GroupVersion{Group: "core.openfeature.dev", Version: "v1alpha2"}
30+
31+
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
32+
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
33+
34+
// AddToScheme adds the types in this group-version to the given scheme.
35+
AddToScheme = SchemeBuilder.AddToScheme
36+
)

0 commit comments

Comments
 (0)