Skip to content

Commit

Permalink
feat!: support OFO v1beta1 API (open-feature#997)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: OFO APIs were updated to version v1beta1, since they are more stable now. Resources of the alpha versions are no longer supported in flagd or flagd-proxy.
  • Loading branch information
odubajDT authored Nov 14, 2023
1 parent 5b82d06 commit bb6f5bf
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 115 deletions.
6 changes: 1 addition & 5 deletions core/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/diegoholiveira/jsonlogic/v3 v3.3.2
github.com/fsnotify/fsnotify v1.7.0
github.com/golang/mock v1.6.0
github.com/open-feature/open-feature-operator v0.2.36
github.com/open-feature/open-feature-operator v0.2.37-0.20231108054703-a97d336468d5
github.com/open-feature/schemas v0.2.8
github.com/prometheus/client_golang v1.17.0
github.com/robfig/cron v1.2.0
Expand Down Expand Up @@ -61,7 +61,6 @@ require (
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-task/slim-sprig v2.20.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
Expand Down Expand Up @@ -95,15 +94,12 @@ require (
golang.org/x/term v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/api v0.28.3 // indirect
k8s.io/apiextensions-apiserver v0.28.3 // indirect
k8s.io/component-base v0.28.3 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
Expand Down
10 changes: 2 additions & 8 deletions core/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,6 @@ github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
Expand Down Expand Up @@ -638,8 +636,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/open-feature/open-feature-operator v0.2.36 h1:dzyZh9JSIRvXkfpM9ynYplNk7vjQFLs9sd5aHhF48z4=
github.com/open-feature/open-feature-operator v0.2.36/go.mod h1:nM7T4oGQukeGmcAFkQm0uwt8WFdDb5hYPjXkm7pHhX4=
github.com/open-feature/open-feature-operator v0.2.37-0.20231108054703-a97d336468d5 h1:ONgFdsDH0uAS3qrmZEQjYqFtqKw/MCkbbQSE33bGBsU=
github.com/open-feature/open-feature-operator v0.2.37-0.20231108054703-a97d336468d5/go.mod h1:nM7T4oGQukeGmcAFkQm0uwt8WFdDb5hYPjXkm7pHhX4=
github.com/open-feature/schemas v0.2.8 h1:oA75hJXpOd9SFgmNI2IAxWZkwzQPUDm7Jyyh3q489wM=
github.com/open-feature/schemas v0.2.8/go.mod h1:vj+rfTsOLlh5PtGGkAbitnJmFPYuTHXTjOy13kzNgKQ=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -1054,7 +1052,6 @@ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNq
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
Expand Down Expand Up @@ -1315,13 +1312,10 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc=
k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A=
k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8=
k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4=
k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo=
k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI=
k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
Expand Down
37 changes: 23 additions & 14 deletions core/pkg/sync/kubernetes/kubernetes_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package kubernetes

import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
Expand All @@ -10,7 +11,7 @@ import (

"github.com/open-feature/flagd/core/pkg/logger"
"github.com/open-feature/flagd/core/pkg/sync"
"github.com/open-feature/open-feature-operator/apis/core/v1alpha1"
"github.com/open-feature/open-feature-operator/apis/core/v1beta1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
Expand All @@ -23,9 +24,9 @@ import (
)

var (
resyncPeriod = 1 * time.Minute
apiVersion = fmt.Sprintf("%s/%s", v1alpha1.GroupVersion.Group, v1alpha1.GroupVersion.Version)
featureFlagConfigurationResource = v1alpha1.GroupVersion.WithResource("featureflagconfigurations")
resyncPeriod = 1 * time.Minute
apiVersion = fmt.Sprintf("%s/%s", v1beta1.GroupVersion.Group, v1beta1.GroupVersion.Version)
featureFlagResource = v1beta1.GroupVersion.WithResource("featureflags")
)

type Sync struct {
Expand Down Expand Up @@ -89,15 +90,15 @@ func (k *Sync) Init(_ context.Context) error {
return fmt.Errorf("unable to parse uri %s: %w", k.URI, err)
}

if err := v1alpha1.AddToScheme(scheme.Scheme); err != nil {
return fmt.Errorf("unable to v1alpha1 types to scheme: %w", err)
if err := v1beta1.AddToScheme(scheme.Scheme); err != nil {
return fmt.Errorf("unable to v1beta1 types to scheme: %w", err)
}

// The created informer will not do resyncs if the given defaultEventHandlerResyncPeriod is zero.
// For more details on resync implications refer to tools/cache/shared_informer.go
factory := dynamicinformer.NewFilteredDynamicSharedInformerFactory(k.dynamicClient, resyncPeriod, k.namespace, nil)

k.informer = factory.ForResource(featureFlagConfigurationResource).Informer()
k.informer = factory.ForResource(featureFlagResource).Informer()

return nil
}
Expand Down Expand Up @@ -191,21 +192,21 @@ func (k *Sync) fetch(ctx context.Context) (string, error) {
}

k.logger.Debug(fmt.Sprintf("resource %s served from the informer cache", k.URI))
return configuration.Spec.FeatureFlagSpec, nil
return marshallFeatureFlagSpec(configuration)
}

// fallback to API access - this is an informer cache miss. Could happen at the startup where cache is not filled
var ff v1alpha1.FeatureFlagConfiguration
var ff v1beta1.FeatureFlag
err = k.readClient.Get(ctx, client.ObjectKey{
Name: k.crdName,
Namespace: k.namespace,
}, &ff)
if err != nil {
return "", fmt.Errorf("unable to fetch FeatureFlagConfiguration %s/%s: %w", k.namespace, k.crdName, err)
return "", fmt.Errorf("unable to fetch FeatureFlag %s/%s: %w", k.namespace, k.crdName, err)
}

k.logger.Debug(fmt.Sprintf("resource %s served from API server", k.URI))
return ff.Spec.FeatureFlagSpec, nil
return marshallFeatureFlagSpec(&ff)
}

func (k *Sync) notify(ctx context.Context, c chan<- INotify) {
Expand Down Expand Up @@ -299,16 +300,16 @@ func updateFuncHandler(oldObj interface{}, newObj interface{}, object client.Obj
}

// toFFCfg attempts to covert unstructured payload to configurations
func toFFCfg(object interface{}) (*v1alpha1.FeatureFlagConfiguration, error) {
func toFFCfg(object interface{}) (*v1beta1.FeatureFlag, error) {
u, ok := object.(*unstructured.Unstructured)
if !ok {
return nil, fmt.Errorf("provided value is not of type *unstructured.Unstructured")
}

var ffObj v1alpha1.FeatureFlagConfiguration
var ffObj v1beta1.FeatureFlag
err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &ffObj)
if err != nil {
return nil, fmt.Errorf("unable to convert unstructured to v1alpha1.FeatureFlagConfiguration: %w", err)
return nil, fmt.Errorf("unable to convert unstructured to v1beta1.FeatureFlag: %w", err)
}

return &ffObj, nil
Expand Down Expand Up @@ -349,3 +350,11 @@ func k8sClusterConfig() (*rest.Config, error) {

return clusterConfig, nil
}

func marshallFeatureFlagSpec(ff *v1beta1.FeatureFlag) (string, error) {
b, err := json.Marshal(ff.Spec.FlagSpec)
if err != nil {
return "", fmt.Errorf("failed to marshall FlagSpec: %s", err.Error())
}
return string(b), nil
}
Loading

0 comments on commit bb6f5bf

Please sign in to comment.