Skip to content

Commit

Permalink
Update unleash image repository (#782)
Browse files Browse the repository at this point in the history
* Update unleash image repository
* Disable SSL for local-ff provider DB
* Add AdminAccessToken
* Add clientAccessToken and update schema
* Bump rhc-osdk-utils version
* Randomize FeatureFlags Admin and Client tokens
* Add feature flags test
  • Loading branch information
Victoremepunto authored Apr 17, 2023
1 parent a3f06f1 commit 77045f5
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ var LocalFFDBPVC = rc.NewSingleResourceIdent(ProvName, "ff_db_pvc", &core.Persis
// LocalFFDBSecret is the ident referring to the local Feature Flags DB secret object.
var LocalFFDBSecret = rc.NewSingleResourceIdent(ProvName, "ff_db_secret", &core.Secret{})

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

type localFeatureFlagsProvider struct {
providers.Provider
}
Expand All @@ -59,6 +62,18 @@ func NewLocalFeatureFlagsProvider(p *providers.Provider) (providers.ClowderProvi
}

func (ff *localFeatureFlagsProvider) EnvProvide() error {

dataInit := createDefaultFFSecMap

namespacedName := providers.GetNamespacedName(ff.Env, "featureflags")

_, err := providers.MakeOrGetSecret(ff.Env, ff.Cache, LocalFFSecret, namespacedName, dataInit)
if err != nil {
raisedErr := errors.Wrap("Couldn't set/get secret", err)
raisedErr.Requeue = true
return raisedErr
}

objList := []rc.ResourceIdent{
LocalFFDeployment,
LocalFFService,
Expand All @@ -68,13 +83,13 @@ func (ff *localFeatureFlagsProvider) EnvProvide() error {
return err
}

nn := types.NamespacedName{
namespacedNameDb := types.NamespacedName{
Name: "featureflags-db",
Namespace: ff.Env.Status.TargetNamespace,
}

dd := &apps.Deployment{}
if err := ff.Cache.Create(LocalFFDBDeployment, nn, dd); err != nil {
if err := ff.Cache.Create(LocalFFDBDeployment, namespacedNameDb, dd); err != nil {
return err
}

Expand All @@ -91,11 +106,11 @@ func (ff *localFeatureFlagsProvider) EnvProvide() error {
}

username := utils.RandString(16)
hostname := fmt.Sprintf("%v.%v.svc", nn.Name, nn.Namespace)
hostname := fmt.Sprintf("%v.%v.svc", namespacedNameDb.Name, namespacedNameDb.Namespace)
passwordEncode := url.QueryEscape(password)
connectionURL := fmt.Sprintf("postgres://%s:%s@%s/%s", username, passwordEncode, hostname, "unleash")

dataInit := func() map[string]string {
dataInitDb := func() map[string]string {

return map[string]string{
"hostname": hostname,
Expand All @@ -108,12 +123,12 @@ func (ff *localFeatureFlagsProvider) EnvProvide() error {
}
}

secMap, err := providers.MakeOrGetSecret(ff.Env, ff.Cache, LocalFFDBSecret, nn, dataInit)
secMapDb, err := providers.MakeOrGetSecret(ff.Env, ff.Cache, LocalFFDBSecret, namespacedNameDb, dataInitDb)
if err != nil {
return errors.Wrap("Couldn't set/get secret", err)
}

err = dbCfg.Populate(secMap)
err = dbCfg.Populate(secMapDb)
if err != nil {
return errors.Wrap("couldn't convert to int", err)
}
Expand All @@ -132,30 +147,30 @@ func (ff *localFeatureFlagsProvider) EnvProvide() error {
},
}

provutils.MakeLocalDB(dd, nn, ff.Env, labels, &dbCfg, "quay.io/cloudservices/postgresql-rds:12-9ee2984", ff.Env.Spec.Providers.FeatureFlags.PVC, "unleash", &res)
provutils.MakeLocalDB(dd, namespacedNameDb, ff.Env, labels, &dbCfg, "quay.io/cloudservices/postgresql-rds:12-9ee2984", ff.Env.Spec.Providers.FeatureFlags.PVC, "unleash", &res)

if err = ff.Cache.Update(LocalFFDBDeployment, dd); err != nil {
return err
}

s := &core.Service{}
if err := ff.Cache.Create(LocalFFDBService, nn, s); err != nil {
if err := ff.Cache.Create(LocalFFDBService, namespacedNameDb, s); err != nil {
return err
}

provutils.MakeLocalDBService(s, nn, ff.Env, labels)
provutils.MakeLocalDBService(s, namespacedNameDb, ff.Env, labels)

if err = ff.Cache.Update(LocalFFDBService, s); err != nil {
return err
}

if ff.Env.Spec.Providers.FeatureFlags.PVC {
pvc := &core.PersistentVolumeClaim{}
if err = ff.Cache.Create(LocalFFDBPVC, nn, pvc); err != nil {
if err = ff.Cache.Create(LocalFFDBPVC, namespacedNameDb, pvc); err != nil {
return err
}

provutils.MakeLocalDBPVC(pvc, nn, ff.Env, sizing.GetDefaultVolCapacity())
provutils.MakeLocalDBPVC(pvc, namespacedNameDb, ff.Env, sizing.GetDefaultVolCapacity())

if err = ff.Cache.Update(LocalFFDBPVC, pvc); err != nil {
return err
Expand All @@ -165,13 +180,29 @@ func (ff *localFeatureFlagsProvider) EnvProvide() error {
return nil
}

func createDefaultFFSecMap() map[string]string {
return map[string]string{
"adminAccessToken": "*:*." + utils.RandHexString(32),
"clientAccessToken": "default:development." + utils.RandHexString(32),
}
}

// CreateDatabase ensures a database is created for the given app. The
// namespaced name passed in must be the actual name of the db resources
func (ff *localFeatureFlagsProvider) Provide(_ *crd.ClowdApp) error {

secret := &core.Secret{}
nn := providers.GetNamespacedName(ff.Env, "featureflags")

if err := ff.Client.Get(ff.Ctx, nn, secret); err != nil {
return err
}

ff.Config.FeatureFlags = &config.FeatureFlagsConfig{
Hostname: fmt.Sprintf("%s-featureflags.%s.svc", ff.Env.Name, ff.Env.Status.TargetNamespace),
Port: 4242,
Scheme: config.FeatureFlagsConfigSchemeHttp,
Hostname: fmt.Sprintf("%s-featureflags.%s.svc", ff.Env.Name, ff.Env.Status.TargetNamespace),
Port: 4242,
Scheme: config.FeatureFlagsConfigSchemeHttp,
ClientAccessToken: utils.StringPtr(string(secret.Data["clientAccessToken"])),
}

return nil
Expand Down Expand Up @@ -199,17 +230,44 @@ func makeLocalFeatureFlags(o obj.ClowdObject, objMap providers.ObjectMap, _ bool

port := int32(4242)

envVars := []core.EnvVar{{
Name: "DATABASE_URL",
ValueFrom: &core.EnvVarSource{
SecretKeyRef: &core.SecretKeySelector{
LocalObjectReference: core.LocalObjectReference{
Name: "featureflags-db",
envVars := []core.EnvVar{
{
Name: "DATABASE_URL",
ValueFrom: &core.EnvVarSource{
SecretKeyRef: &core.SecretKeySelector{
LocalObjectReference: core.LocalObjectReference{
Name: "featureflags-db",
},
Key: "connectionURL",
},
},
},
{
Name: "DATABASE_SSL",
Value: "false",
},
{
Name: "INIT_CLIENT_API_TOKENS",
ValueFrom: &core.EnvVarSource{
SecretKeyRef: &core.SecretKeySelector{
LocalObjectReference: core.LocalObjectReference{
Name: nn.Name,
},
Key: "clientAccessToken",
},
},
},
{
Name: "INIT_ADMIN_API_TOKENS",
ValueFrom: &core.EnvVarSource{
SecretKeyRef: &core.SecretKeySelector{
LocalObjectReference: core.LocalObjectReference{
Name: nn.Name,
},
Key: "adminAccessToken",
},
Key: "connectionURL",
},
},
},
}

ports := []core.ContainerPort{{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
p "github.com/RedHatInsights/clowder/controllers/cloud.redhat.com/providers"
)

var DefaultImageFeatureFlagsUnleash = "quay.io/cloudservices/unleash-docker:3.9"
var DefaultImageFeatureFlagsUnleash = "quay.io/cloudservices/unleash-docker:4.22.3"

// ProvName identifies the featureflags provider.
var ProvName = "featureflags"
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.18
require (
github.com/RedHatInsights/cyndi-operator v0.1.9
github.com/RedHatInsights/go-difflib v1.0.0
github.com/RedHatInsights/rhc-osdk-utils v0.7.1
github.com/RedHatInsights/rhc-osdk-utils v0.8.0
github.com/RedHatInsights/strimzi-client-go v0.28.1
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1
github.com/go-logr/logr v1.2.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ github.com/RedHatInsights/cyndi-operator v0.1.9 h1:0KAeAtI3x7nND1O/bt/hHJdYorw30
github.com/RedHatInsights/cyndi-operator v0.1.9/go.mod h1:aqq1uTYlZhB93bE9N9AohrMQ55y22v6dMK3gx1b7dbA=
github.com/RedHatInsights/go-difflib v1.0.0 h1:BoruyjZfxO81sEynhkG6c4SMAQOjuBWezcJxtGK8dyw=
github.com/RedHatInsights/go-difflib v1.0.0/go.mod h1:UMKOFdypYfrKT1B1nbGodM09nhOiAmcjes8qWP7Myrs=
github.com/RedHatInsights/rhc-osdk-utils v0.7.1 h1:LMRlVLvbxIkh1/dGJpjm2/Lx0RlJGJyQI/7L16X0+vo=
github.com/RedHatInsights/rhc-osdk-utils v0.7.1/go.mod h1:804rN1vcOYysCQ04kpcJUwQF5QfZh6Lhh1ne0pbF4So=
github.com/RedHatInsights/rhc-osdk-utils v0.8.0 h1:q3ehOl4DOjZeKlpkzAdXu/Vt6yEeNwWlLEZ1ofC1WAE=
github.com/RedHatInsights/rhc-osdk-utils v0.8.0/go.mod h1:804rN1vcOYysCQ04kpcJUwQF5QfZh6Lhh1ne0pbF4So=
github.com/RedHatInsights/strimzi-client-go v0.28.1 h1:YhP+HQ4c3P1K43iDLqzGfRX0BVYuO2J/A7RC1+v3AF0=
github.com/RedHatInsights/strimzi-client-go v0.28.1/go.mod h1:jGWJzu7pkuLMKVou555oDdFvZq6agx+VsQ49XgfbQkg=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
Expand Down
1 change: 1 addition & 0 deletions tests/kuttl/test-ff-local/02-json-asserts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ commands:
- script: jq -r '.featureFlags.hostname == "test-ff-local-featureflags.test-ff-local.svc"' -e < /tmp/test-ff-local-json
- script: jq -r '.featureFlags.port == 4242' -e < /tmp/test-ff-local-json
- script: jq -r '.featureFlags.scheme == "http"' -e < /tmp/test-ff-local-json
- script: sh test_feature_flags.sh
61 changes: 61 additions & 0 deletions tests/kuttl/test-ff-local/test_feature_flags.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash

FEATURE_FLAGS_POD=$(kubectl -n test-ff-local get pod -l env-app=test-ff-local-featureflags --output=jsonpath={.items..metadata.name})
ADMIN_TOKEN=$(kubectl -n test-ff-local get secret test-ff-local-featureflags -o json | jq -r '.data.adminAccessToken | @base64d')
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() {

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

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

post_request() {

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

kubectl exec -n test-ff-local "$FEATURE_FLAGS_POD" -- wget -q -O- \
--post-data "$DATA" \
--header "Content-Type: application/json" \
--header "Authorization: $TOKEN" \
"localhost:4242${ENDPOINT}"
}

if get_request "$CLIENT_TOKEN" "/api/client/features/$FEATURE_TOGGLE_NAME"; then
echo "Feature toggle '$FEATURE_TOGGLE_NAME' should not exist"
exit 1
fi


if ! post_request "$ADMIN_TOKEN" \
"/api/admin/projects/default/features" \
"{ \"name\": \"$FEATURE_TOGGLE_NAME\" }"; then
echo "Error creating feature flag!"
exit 1
fi

if ! get_request "$CLIENT_TOKEN" "/api/client/features/$FEATURE_TOGGLE_NAME"; then
echo "Feature toggle '$FEATURE_TOGGLE_NAME' should exist"
fi

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

if ! post_request "$ADMIN_TOKEN" \
"/api/admin/projects/default/features/$FEATURE_TOGGLE_NAME/environments/development/on" ; then
echo "Error enabling feature toggle '$FEATURE_TOGGLE_NAME'"
exit 1
fi

if [ 'true' != "$(get_request "$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 77045f5

Please sign in to comment.