Skip to content

Commit

Permalink
Deploy unleash-edge alongside local featureFlags
Browse files Browse the repository at this point in the history
  • Loading branch information
ezr-ondrej committed Jan 28, 2025
1 parent 5211e72 commit 7c65ca8
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 13 deletions.
3 changes: 2 additions & 1 deletion apis/cloud.redhat.com/v1alpha1/clowdenvironment_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,8 @@ type ObjectStoreConfig struct {
}

type FeatureFlagsImages struct {
Unleash string `json:"unleash,omitempty"`
Unleash string `json:"unleash,omitempty"`
UnleashEdge string `json:"unleashEdge,omitempty"`
}

// FeatureFlagsMode details the mode of operation of the Clowder FeatureFlags
Expand Down
21 changes: 11 additions & 10 deletions controllers/cloud.redhat.com/clowderconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ import (

type ClowderConfig struct {
Images struct {
MBOP string `json:"mbop"`
Caddy string `json:"caddy"`
CaddyGateway string `json:"caddyGateway"`
Keycloak string `json:"Keycloak"`
Mocktitlements string `json:"mocktitlements"`
CaddyReverseProxy string `json:"caddyReverseProxy"`
ObjectStoreMinio string `json:"objectStoreMinio"`
FeatureFlagsUnleash string `json:"featureFlagsUnleash"`
TokenRefresher string `json:"tokenRefresher"`
OtelCollector string `json:"otelCollector"`
MBOP string `json:"mbop"`
Caddy string `json:"caddy"`
CaddyGateway string `json:"caddyGateway"`
Keycloak string `json:"Keycloak"`
Mocktitlements string `json:"mocktitlements"`
CaddyReverseProxy string `json:"caddyReverseProxy"`
ObjectStoreMinio string `json:"objectStoreMinio"`
FeatureFlagsUnleash string `json:"featureFlagsUnleash"`
FeatureFlagsUnleashEdge string `json:"featureFlagsUnleashEdge"`
TokenRefresher string `json:"tokenRefresher"`
OtelCollector string `json:"otelCollector"`
} `json:"images"`
DebugOptions struct {
Logging struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,20 @@ import (
"github.com/RedHatInsights/rhc-osdk-utils/utils"
)

const featureFlagsPort = 4242

// LocalFFDeployment is the ident referring to the local Feature Flags deployment object.
var LocalFFDeployment = rc.NewSingleResourceIdent(ProvName, "ff_deployment", &apps.Deployment{})

// LocalFFService is the ident referring to the local Feature Flags service object.
var LocalFFService = rc.NewSingleResourceIdent(ProvName, "ff_service", &core.Service{})

// LocalFFEdgeDeployment is the ident referring to the local Unleash edge deployment object.
var LocalFFEdgeDeployment = rc.NewSingleResourceIdent(ProvName, "ff_edge_deployment", &apps.Deployment{})

// LocalFFEdgeService is the ident referring to the local Unleash edge service object.
var LocalFFEdgeService = rc.NewSingleResourceIdent(ProvName, "ff_service", &core.Service{})

// LocalFFSecret is the ident referring to the local Feature Flags secret object.
var LocalFFSecret = rc.NewSingleResourceIdent(ProvName, "ff_secret", &core.Secret{})

Expand All @@ -53,6 +61,8 @@ func NewLocalFeatureFlagsProvider(p *providers.Provider) (providers.ClowderProvi
p.Cache.AddPossibleGVKFromIdent(
LocalFFDeployment,
LocalFFService,
LocalFFEdgeDeployment,
LocalFFEdgeService,
LocalFFSecret,
LocalFFDBDeployment,
LocalFFDBService,
Expand Down Expand Up @@ -84,6 +94,15 @@ func (ff *localFeatureFlagsProvider) EnvProvide() error {
return err
}

objList2 := []rc.ResourceIdent{
LocalFFEdgeDeployment,
LocalFFEdgeService,
}

if err := providers.CachedMakeComponent(ff.Cache, objList2, ff.Env, "featureflags-edge", makeLocalFeatureFlagsEdge, false, ff.Env.IsNodePort()); err != nil {
return err
}

namespacedNameDb := types.NamespacedName{
Name: "featureflags-db",
Namespace: ff.Env.Status.TargetNamespace,
Expand Down Expand Up @@ -229,7 +248,7 @@ func makeLocalFeatureFlags(o obj.ClowdObject, objMap providers.ObjectMap, _ bool

dd.Spec.Template.ObjectMeta.Labels = labels

port := int32(4242)
port := int32(featureFlagsPort)

envVars := []core.EnvVar{
{
Expand Down Expand Up @@ -257,7 +276,7 @@ func makeLocalFeatureFlags(o obj.ClowdObject, objMap providers.ObjectMap, _ bool
Path: "/health",
Port: intstr.IntOrString{
Type: intstr.Int,
IntVal: 4242,
IntVal: featureFlagsPort,
},
},
}
Expand Down Expand Up @@ -319,3 +338,106 @@ func makeLocalFeatureFlags(o obj.ClowdObject, objMap providers.ObjectMap, _ bool
utils.MakeService(svc, nn, labels, servicePorts, o, nodePort)
return nil
}

func makeLocalFeatureFlagsEdge(o obj.ClowdObject, objMap providers.ObjectMap, _ bool, nodePort bool) error {

nnFF := providers.GetNamespacedName(o, "featureflags")
nn := providers.GetNamespacedName(o, "featureflags-edge")

dd := objMap[LocalFFEdgeDeployment].(*apps.Deployment)
svc := objMap[LocalFFEdgeService].(*core.Service)

labels := o.GetLabels()
labels["env-app"] = nn.Name
labels["service"] = "featureflags-edge"
labeler := utils.MakeLabeler(nn, labels, o)

labeler(dd)

replicas := int32(1)

dd.Spec.Replicas = &replicas
dd.Spec.Selector = &metav1.LabelSelector{MatchLabels: labels}

dd.Spec.Template.ObjectMeta.Labels = labels

portEdge := int32(3063)

envVarsEdge := []core.EnvVar{
{
// communication with the main featureflags service on localhost
Name: "UPSTREAM_URL",
Value: fmt.Sprintf("http://%s:%d", nnFF.Name, featureFlagsPort),
},
}
envVarsEdge = provutils.AppendEnvVarsFromSecret(envVarsEdge, nnFF.Name,
provutils.NewSecretEnvVar("TOKENS", "clientAccessToken"))

portsEdge := []core.ContainerPort{{
Name: "service",
ContainerPort: portEdge,
Protocol: "TCP",
}}

readinessProbeEdge := core.Probe{
ProbeHandler: core.ProbeHandler{
Exec: &core.ExecAction{
Command: []string{"/unleash-edge", "ready"},
},
},
InitialDelaySeconds: 1,
TimeoutSeconds: 5,
PeriodSeconds: 30,
SuccessThreshold: 1,
FailureThreshold: 3,
}

livenessProbeEdge := core.Probe{
ProbeHandler: core.ProbeHandler{
Exec: &core.ExecAction{
Command: []string{"/unleash-edge", "health"},
},
},
InitialDelaySeconds: 30,
TimeoutSeconds: 5,
PeriodSeconds: 30,
SuccessThreshold: 1,
FailureThreshold: 3,
}

env, ok := o.(*crd.ClowdEnvironment)
if !ok {
return fmt.Errorf("could not get env")
}

ce := core.Container{
Name: nn.Name,
Image: GetFeatureFlagsUnleashEdgeImage(env),
Env: envVarsEdge,
Ports: portsEdge,
Args: []string{"edge"},
ReadinessProbe: &readinessProbeEdge,
LivenessProbe: &livenessProbeEdge,
ImagePullPolicy: core.PullIfNotPresent,
Resources: core.ResourceRequirements{
Requests: core.ResourceList{
"memory": resource.MustParse("100Mi"),
"cpu": resource.MustParse("100m"),
},
},
}

dd.Spec.Template.Spec.Containers = []core.Container{ce}
dd.Spec.Template.SetLabels(labels)

servicePorts := []core.ServicePort{{
Name: "featureflags-edge",
Port: portEdge,
Protocol: "TCP",
TargetPort: intstr.FromInt(int(portEdge)),
}}

utils.MakeService(svc, nn, labels, servicePorts, o, nodePort)

return nil
}
11 changes: 11 additions & 0 deletions controllers/cloud.redhat.com/providers/featureflags/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
)

var DefaultImageFeatureFlagsUnleash = "unleashorg/unleash-server:5.6.9"
var DefaultImageFeatureFlagsUnleashEdge = "unleashorg/unleash-edge:v19.6.3"

func GetFeatureFlagsUnleashImage(env *crd.ClowdEnvironment) string {
if env.Spec.Providers.FeatureFlags.Images.Unleash != "" {
Expand All @@ -21,6 +22,16 @@ func GetFeatureFlagsUnleashImage(env *crd.ClowdEnvironment) string {
return DefaultImageFeatureFlagsUnleash
}

func GetFeatureFlagsUnleashEdgeImage(env *crd.ClowdEnvironment) string {
if env.Spec.Providers.FeatureFlags.Images.UnleashEdge != "" {
return env.Spec.Providers.FeatureFlags.Images.UnleashEdge
}
if clowderconfig.LoadedConfig.Images.FeatureFlagsUnleashEdge != "" {
return clowderconfig.LoadedConfig.Images.FeatureFlagsUnleashEdge
}
return DefaultImageFeatureFlagsUnleashEdge
}

// ProvName identifies the featureflags provider.
var ProvName = "featureflags"

Expand Down
21 changes: 21 additions & 0 deletions tests/kuttl/test-ff-local/test_feature_flags.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ ADMIN_TOKEN=$(kubectl -n test-ff-local get secret test-ff-local-featureflags -o
CLIENT_TOKEN=$(kubectl -n test-ff-local get secret test-ff-local-featureflags -o json | jq -r '.data.clientAccessToken | @base64d')
FEATURE_TOGGLE_NAME='my-feature-toggle-1'

get_request_edge() {

local TOKEN="$1"
local ENDPOINT="$2"

kubectl exec -n test-ff-local "$FEATURE_FLAGS_POD" -- wget -q -O- \
--header "Authorization: $TOKEN" "test-ff-local-featureflags-edge:3063${ENDPOINT}"
}

get_request() {

local TOKEN="$1"
Expand Down Expand Up @@ -59,3 +68,15 @@ if [ 'true' != "$(get_request "$CLIENT_TOKEN" "/api/client/features/$FEATURE_TOG
echo "Feature toggle '$FEATURE_TOGGLE_NAME' should be enabled"
exit 1
fi

echo "Waiting for edge to sync"
sleep 3

if ! get_request_edge "$CLIENT_TOKEN" "/api/client/features/$FEATURE_TOGGLE_NAME"; then
echo "Feature toggle '$FEATURE_TOGGLE_NAME' should be available through edge"
fi

if [ 'true' != "$(get_request_edge "$CLIENT_TOKEN" "/api/client/features/$FEATURE_TOGGLE_NAME" | jq '.enabled==true')" ]; then
echo "Feature toggle '$FEATURE_TOGGLE_NAME' should be enabled"
exit 1
fi

0 comments on commit 7c65ca8

Please sign in to comment.