Skip to content

Commit

Permalink
feat: add function to merge remote vars into build pod
Browse files Browse the repository at this point in the history
  • Loading branch information
shreddedbacon committed Jun 28, 2022
1 parent 90c335d commit e2d90b8
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 61 deletions.
1 change: 1 addition & 0 deletions controllers/v1beta1/build_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type LagoonBuildReconciler struct {
BuildQoS BuildQoS
NativeCronPodMinFrequency int
LagoonTargetName string
LagoonFeatureFlags map[string]string
ProxyConfig ProxyConfig
}

Expand Down
7 changes: 7 additions & 0 deletions controllers/v1beta1/build_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,13 @@ func (r *LagoonBuildReconciler) processBuild(ctx context.Context, opLog logr.Log
Value: r.LFFDefaultRWX2RWO,
})
}
// add any LAGOON_FEATURE_FLAG_ variables in the controller into the build pods
for fName, fValue := range r.LagoonFeatureFlags {
podEnvs = append(podEnvs, corev1.EnvVar{
Name: fName,
Value: fValue,
})
}
// Use the build image in the controller definition
buildImage := r.BuildImage
if lagoonBuild.Spec.Build.Image != "" {
Expand Down
44 changes: 44 additions & 0 deletions internal/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/base32"
"fmt"
"math/rand"
"os"
"regexp"
"sort"
"strconv"
Expand Down Expand Up @@ -296,3 +297,46 @@ func ShortenEnvironment(project, environment string) string {
}
return environment
}

// GetLagoonFeatureFlags pull all the environment variables and check if there are any with the flag prefix
func GetLagoonFeatureFlags() map[string]string {
flags := make(map[string]string)
for _, envVar := range os.Environ() {
envVarSplit := strings.SplitN(envVar, "=", 2)
// if the variable name contains the flag prefix, add it to the map
if strings.Contains(envVarSplit[0], "LAGOON_FEATURE_FLAG_") {
flags[envVarSplit[0]] = envVarSplit[1]
}
}
return flags
}

// GetEnv get environment variable
func GetEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}

// GetEnvInt get environment variable as int
func GetEnvInt(key string, fallback int) int {
if value, ok := os.LookupEnv(key); ok {
valueInt, e := strconv.Atoi(value)
if e == nil {
return valueInt
}
}
return fallback
}

// GetEnvBool get environment variable as bool
// accepts fallback values 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False
// anything else is false.
func GetEnvBool(key string, fallback bool) bool {
if value, ok := os.LookupEnv(key); ok {
rVal, _ := strconv.ParseBool(value)
return rVal
}
return fallback
}
39 changes: 39 additions & 0 deletions internal/helpers/helpers_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package helpers

import (
"os"
"reflect"
"testing"
)

Expand Down Expand Up @@ -205,3 +207,40 @@ func TestShortenEnvironment(t *testing.T) {
})
}
}

func TestGetLagoonFeatureFlags(t *testing.T) {
tests := []struct {
name string
set map[string]string
want map[string]string
}{
{
name: "test1",
set: map[string]string{
"LAGOON_FEATURE_FLAG_ABC": "enabled",
"LAGOON_FEATURE_FLAG_123": "enabled",
"OTHERS": "path noises",
},
want: map[string]string{
"LAGOON_FEATURE_FLAG_ABC": "enabled",
"LAGOON_FEATURE_FLAG_123": "enabled",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for e, v := range tt.set {
os.Setenv(e, v)
}
if got := GetLagoonFeatureFlags(); !reflect.DeepEqual(got, tt.want) {
for e := range tt.set {
os.Unsetenv(e)
}
t.Errorf("GetLagoonFeatureFlags() = %v, want %v", got, tt.want)
}
for e := range tt.set {
os.Unsetenv(e)
}
})
}
}
96 changes: 35 additions & 61 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"

Expand All @@ -36,6 +35,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/uselagoon/remote-controller/internal/harbor"
"github.com/uselagoon/remote-controller/internal/helpers"
"github.com/uselagoon/remote-controller/internal/metrics"

"gopkg.in/robfig/cron.v2"
Expand Down Expand Up @@ -326,14 +326,14 @@ func main() {
flag.Parse()

// get overrides from environment variables
mqUser = getEnv("RABBITMQ_USERNAME", mqUser)
mqPass = getEnv("RABBITMQ_PASSWORD", mqPass)
mqHost = getEnv("RABBITMQ_HOSTNAME", mqHost)
lagoonTargetName = getEnv("LAGOON_TARGET_NAME", lagoonTargetName)
lagoonAppID = getEnv("LAGOON_APP_ID", lagoonAppID)
pendingMessageCron = getEnv("PENDING_MESSAGE_CRON", pendingMessageCron)
overrideBuildDeployImage = getEnv("OVERRIDE_BUILD_DEPLOY_DIND_IMAGE", overrideBuildDeployImage)
namespacePrefix = getEnv("NAMESPACE_PREFIX", namespacePrefix)
mqUser = helpers.GetEnv("RABBITMQ_USERNAME", mqUser)
mqPass = helpers.GetEnv("RABBITMQ_PASSWORD", mqPass)
mqHost = helpers.GetEnv("RABBITMQ_HOSTNAME", mqHost)
lagoonTargetName = helpers.GetEnv("LAGOON_TARGET_NAME", lagoonTargetName)
lagoonAppID = helpers.GetEnv("LAGOON_APP_ID", lagoonAppID)
pendingMessageCron = helpers.GetEnv("PENDING_MESSAGE_CRON", pendingMessageCron)
overrideBuildDeployImage = helpers.GetEnv("OVERRIDE_BUILD_DEPLOY_DIND_IMAGE", overrideBuildDeployImage)
namespacePrefix = helpers.GetEnv("NAMESPACE_PREFIX", namespacePrefix)
if len(namespacePrefix) > 8 {
// truncate the namespace prefix to 8 characters so that a really long prefix
// does not become a problem, and namespaces are still somewhat identifiable.
Expand All @@ -345,30 +345,30 @@ func main() {
// this is also used by the controller as the namespace that resources will be created in initially when received by the queue
// this can be defined using `valueFrom.fieldRef.fieldPath: metadata.namespace` in any deployments to get the
// namespace from where the controller is running
controllerNamespace = getEnv("CONTROLLER_NAMESPACE", controllerNamespace)
controllerNamespace = helpers.GetEnv("CONTROLLER_NAMESPACE", controllerNamespace)
if controllerNamespace == "" {
setupLog.Error(fmt.Errorf("controller-namespace is empty"), "unable to start manager")
os.Exit(1)
}
lagoonAPIHost = getEnv("TASK_API_HOST", lagoonAPIHost)
lagoonSSHHost = getEnv("TASK_SSH_HOST", lagoonSSHHost)
lagoonSSHPort = getEnv("TASK_SSH_PORT", lagoonSSHPort)
lagoonAPIHost = helpers.GetEnv("TASK_API_HOST", lagoonAPIHost)
lagoonSSHHost = helpers.GetEnv("TASK_SSH_HOST", lagoonSSHHost)
lagoonSSHPort = helpers.GetEnv("TASK_SSH_PORT", lagoonSSHPort)

nativeCronPodMinFrequency = getEnvInt("NATIVE_CRON_POD_MINIMUM_FREQUENCY", nativeCronPodMinFrequency)
nativeCronPodMinFrequency = helpers.GetEnvInt("NATIVE_CRON_POD_MINIMUM_FREQUENCY", nativeCronPodMinFrequency)

// harbor envvars
harborURL = getEnv("HARBOR_URL", harborURL)
harborAPI = getEnv("HARBOR_API", harborAPI)
harborUsername = getEnv("HARBOR_USERNAME", harborUsername)
harborPassword = getEnv("HARBOR_PASSWORD", harborPassword)
harborRobotPrefix = getEnv("HARBOR_ROBOT_PREFIX", harborRobotPrefix)
harborWebhookAdditionEnabled = getEnvBool("HARBOR_WEBHOOK_ADDITION_ENABLED", harborWebhookAdditionEnabled)
harborLagoonWebhook = getEnv("HARBOR_LAGOON_WEBHOOK", harborLagoonWebhook)
harborWebhookEventTypes = getEnv("HARBOR_WEBHOOK_EVENTTYPES", harborWebhookEventTypes)
harborRobotDeleteDisabled = getEnvBool("HARBOR_ROBOT_DELETE_DISABLED", harborRobotDeleteDisabled)
harborExpiryInterval = getEnv("HARBOR_EXPIRY_INTERVAL", harborExpiryInterval)
harborRotateInterval = getEnv("HARBOR_ROTATE_INTERVAL", harborRotateInterval)
harborRobotAccountExpiry = getEnv("HARBOR_ROTATE_ACCOUNT_EXPIRY", harborRobotAccountExpiry)
harborURL = helpers.GetEnv("HARBOR_URL", harborURL)
harborAPI = helpers.GetEnv("HARBOR_API", harborAPI)
harborUsername = helpers.GetEnv("HARBOR_USERNAME", harborUsername)
harborPassword = helpers.GetEnv("HARBOR_PASSWORD", harborPassword)
harborRobotPrefix = helpers.GetEnv("HARBOR_ROBOT_PREFIX", harborRobotPrefix)
harborWebhookAdditionEnabled = helpers.GetEnvBool("HARBOR_WEBHOOK_ADDITION_ENABLED", harborWebhookAdditionEnabled)
harborLagoonWebhook = helpers.GetEnv("HARBOR_LAGOON_WEBHOOK", harborLagoonWebhook)
harborWebhookEventTypes = helpers.GetEnv("HARBOR_WEBHOOK_EVENTTYPES", harborWebhookEventTypes)
harborRobotDeleteDisabled = helpers.GetEnvBool("HARBOR_ROBOT_DELETE_DISABLED", harborRobotDeleteDisabled)
harborExpiryInterval = helpers.GetEnv("HARBOR_EXPIRY_INTERVAL", harborExpiryInterval)
harborRotateInterval = helpers.GetEnv("HARBOR_ROTATE_INTERVAL", harborRotateInterval)
harborRobotAccountExpiry = helpers.GetEnv("HARBOR_ROTATE_ACCOUNT_EXPIRY", harborRobotAccountExpiry)
harborExpiryIntervalDuration := 2 * 24 * time.Hour
harborRotateIntervalDuration := 30 * 24 * time.Hour
harborRobotAccountExpiryDuration := 30 * 24 * time.Hour
Expand All @@ -393,18 +393,18 @@ func main() {

// Fastly configuration options
// the service id should be that for the cluster which will be used as the default no-cache passthrough
fastlyServiceID = getEnv("FASTLY_SERVICE_ID", fastlyServiceID)
fastlyServiceID = helpers.GetEnv("FASTLY_SERVICE_ID", fastlyServiceID)
// this is used to control setting the service id into build pods
fastlyWatchStatus = getEnvBool("FASTLY_WATCH_STATUS", fastlyWatchStatus)
fastlyWatchStatus = helpers.GetEnvBool("FASTLY_WATCH_STATUS", fastlyWatchStatus)

if enablePodProxy {
httpProxy = getEnv("HTTP_PROXY", httpProxy)
httpsProxy = getEnv("HTTPS_PROXY", httpsProxy)
noProxy = getEnv("HTTP_PROXY", noProxy)
httpProxy = helpers.GetEnv("HTTP_PROXY", httpProxy)
httpsProxy = helpers.GetEnv("HTTPS_PROXY", httpsProxy)
noProxy = helpers.GetEnv("HTTP_PROXY", noProxy)
if podsUseDifferentProxy {
httpProxy = getEnv("LAGOON_HTTP_PROXY", httpProxy)
httpsProxy = getEnv("LAGOON_HTTPS_PROXY", httpsProxy)
noProxy = getEnv("LAGOON_HTTP_PROXY", noProxy)
httpProxy = helpers.GetEnv("LAGOON_HTTP_PROXY", httpProxy)
httpsProxy = helpers.GetEnv("LAGOON_HTTPS_PROXY", httpsProxy)
noProxy = helpers.GetEnv("LAGOON_HTTP_PROXY", noProxy)
}
}

Expand Down Expand Up @@ -709,6 +709,7 @@ func main() {
BuildQoS: buildQoSConfig,
NativeCronPodMinFrequency: nativeCronPodMinFrequency,
LagoonTargetName: lagoonTargetName,
LagoonFeatureFlags: helpers.GetLagoonFeatureFlags(),
ProxyConfig: lagoonv1beta1ctrl.ProxyConfig{
HTTPProxy: httpProxy,
HTTPSProxy: httpsProxy,
Expand Down Expand Up @@ -769,33 +770,6 @@ func main() {
}
}

func getEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}

func getEnvInt(key string, fallback int) int {
if value, ok := os.LookupEnv(key); ok {
valueInt, e := strconv.Atoi(value)
if e == nil {
return valueInt
}
}
return fallback
}

// accepts fallback values 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False
// anything else is false.
func getEnvBool(key string, fallback bool) bool {
if value, ok := os.LookupEnv(key); ok {
rVal, _ := strconv.ParseBool(value)
return rVal
}
return fallback
}

func init() {
if tlsSkipVerify {
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
Expand Down

0 comments on commit e2d90b8

Please sign in to comment.