Skip to content

Commit

Permalink
Merge pull request #71 from uselagoon/ingress-class
Browse files Browse the repository at this point in the history
  • Loading branch information
shreddedbacon authored Aug 1, 2022
2 parents 45220a0 + f175a1a commit b5537dc
Show file tree
Hide file tree
Showing 22 changed files with 1,013 additions and 20 deletions.
87 changes: 86 additions & 1 deletion cmd/template_ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestTemplateRoutes(t *testing.T) {
cacheNoCache string
serviceID string
secretPrefix string
ingressClass string
projectVars string
envVars string
lagoonVersion string
Expand Down Expand Up @@ -269,6 +270,86 @@ func TestTemplateRoutes(t *testing.T) {
},
want: "../test-resources/template-ingress/test12-results",
},
{
name: "test13 ingress class from default flag",
args: args{
alertContact: "alertcontact",
statusPageID: "statuspageid",
projectName: "example-project",
environmentName: "main",
environmentType: "production",
buildType: "branch",
lagoonVersion: "v2.7.x",
branch: "main",
projectVars: `[{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"}]`,
envVars: `[]`,
secretPrefix: "fastly-api-",
ingressClass: "nginx",
lagoonYAML: "../test-resources/template-ingress/test13/lagoon.yml",
templatePath: "../test-resources/template-ingress/output",
},
want: "../test-resources/template-ingress/test13-results",
},
{
name: "test14 ingress class from lagoon.yml should overwrite default and featureflag variable",
args: args{
alertContact: "alertcontact",
statusPageID: "statuspageid",
projectName: "example-project",
environmentName: "main",
environmentType: "production",
buildType: "branch",
lagoonVersion: "v2.7.x",
branch: "main",
ingressClass: "nginx",
projectVars: `[{"name":"LAGOON_FEATURE_FLAG_INGRESS_CLASS","value":"nginx","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"}]`,
envVars: `[]`,
secretPrefix: "fastly-api-",
lagoonYAML: "../test-resources/template-ingress/test14/lagoon.yml",
templatePath: "../test-resources/template-ingress/output",
},
want: "../test-resources/template-ingress/test14-results",
},
{
name: "test15a ingress class from lagoon api project scope",
args: args{
alertContact: "alertcontact",
statusPageID: "statuspageid",
projectName: "example-project",
environmentName: "main",
environmentType: "production",
buildType: "branch",
lagoonVersion: "v2.7.x",
branch: "main",
ingressClass: "nginx",
projectVars: `[{"name":"LAGOON_FEATURE_FLAG_INGRESS_CLASS","value":"custom-ingress","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"}]`,
envVars: `[]`,
secretPrefix: "fastly-api-",
lagoonYAML: "../test-resources/template-ingress/test15/lagoon.yml",
templatePath: "../test-resources/template-ingress/output",
},
want: "../test-resources/template-ingress/test15-results",
},
{
name: "test15b ingress class from lagoon api environment scope",
args: args{
alertContact: "alertcontact",
statusPageID: "statuspageid",
projectName: "example-project",
environmentName: "main",
environmentType: "production",
buildType: "branch",
lagoonVersion: "v2.7.x",
branch: "main",
ingressClass: "nginx",
projectVars: `[{"name":"LAGOON_FEATURE_FLAG_INGRESS_CLASS","value":"project-custom-ingress","scope":"build"},{"name":"LAGOON_SYSTEM_ROUTER_PATTERN","value":"${service}-${project}-${environment}.example.com","scope":"internal_system"}]`,
envVars: `[{"name":"LAGOON_FEATURE_FLAG_INGRESS_CLASS","value":"custom-ingress","scope":"build"}]`,
secretPrefix: "fastly-api-",
lagoonYAML: "../test-resources/template-ingress/test15/lagoon.yml",
templatePath: "../test-resources/template-ingress/output",
},
want: "../test-resources/template-ingress/test15-results",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -337,6 +418,10 @@ func TestTemplateRoutes(t *testing.T) {
if err != nil {
t.Errorf("%v", err)
}
err = os.Setenv("LAGOON_FEATURE_FLAG_DEFAULT_INGRESS_CLASS", tt.args.ingressClass)
if err != nil {
t.Errorf("%v", err)
}
lagoonYml = tt.args.lagoonYAML
templateValues = tt.args.valuesFilePath

Expand Down Expand Up @@ -404,7 +489,7 @@ func TestTemplateRoutes(t *testing.T) {
t.Errorf("resulting templates do not match")
}
t.Cleanup(func() {
helpers.UnsetEnvVars(nil)
helpers.UnsetEnvVars([]helpers.EnvironmentVariable{{Name: "LAGOON_FEATURE_FLAG_DEFAULT_INGRESS_CLASS"}})
})
})
}
Expand Down
1 change: 1 addition & 0 deletions internal/generator/buildvalues.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type BuildValues struct {
ServiceTypeOverrides *lagoon.EnvironmentVariable `json:"serviceTypeOverrides"`
DBaaSEnvironmentTypeOverrides *lagoon.EnvironmentVariable `json:"dbaasEnvironmentTypeOverrides"`
DBaaSFallbackSingle bool `json:"dbaasFallbackSingle"`
IngressClass string `json:"ingressClass"`
}

type MonitoringConfig struct {
Expand Down
34 changes: 34 additions & 0 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package generator
import (
"encoding/json"
"fmt"
"os"
"strings"

"github.com/uselagoon/build-deploy-tool/internal/helpers"
Expand Down Expand Up @@ -169,6 +170,10 @@ func NewGenerator(
// this will later be used to add `runtime|global` scope into the `lagoon-env` configmap
lagoonEnvVars = lagoon.MergeVariables(mergedVariables, configVars)

// check the environment for INGRESS_CLASS flag, will be "" if there are none found
ingressClass := CheckFeatureFlag("INGRESS_CLASS", lagoonEnvVars, debug)
buildValues.IngressClass = ingressClass

// get any variables from the API here
lagoonServiceTypes, _ := lagoon.GetLagoonVariable("LAGOON_SERVICE_TYPES", nil, lagoonEnvVars)
buildValues.ServiceTypeOverrides = lagoonServiceTypes
Expand Down Expand Up @@ -253,3 +258,32 @@ func collectBuildVariables(buildValues BuildValues) []lagoon.EnvironmentVariable
vars = append(vars, lagoon.EnvironmentVariable{Name: "LAGOON_AUTOGENERATED_ROUTES", Value: strings.Join(buildValues.AutogeneratedRoutes, ","), Scope: "runtime"})
return vars
}

// GetEnv gets an environment variable
func CheckFeatureFlag(key string, envVariables []lagoon.EnvironmentVariable, debug bool) string {
// check for force value
if value, ok := os.LookupEnv(fmt.Sprintf("LAGOON_FEATURE_FLAG_FORCE_%s", key)); ok {
if debug {
fmt.Println(fmt.Sprintf("Using forced flag value from build variable %s", fmt.Sprintf("LAGOON_FEATURE_FLAG_FORCE_%s", key)))
}
return value
}
// check lagoon environment variables
for _, lVar := range envVariables {
if strings.Contains(lVar.Name, fmt.Sprintf("LAGOON_FEATURE_FLAG_%s", key)) {
if debug {
fmt.Println(fmt.Sprintf("Using flag value from Lagoon environment variable %s", fmt.Sprintf("LAGOON_FEATURE_FLAG_%s", key)))
}
return lVar.Value
}
}
// return default
if value, ok := os.LookupEnv(fmt.Sprintf("LAGOON_FEATURE_FLAG_DEFAULT_%s", key)); ok {
if debug {
fmt.Println(fmt.Sprintf("Using default flag value from build variable %s", fmt.Sprintf("LAGOON_FEATURE_FLAG_DEFAULT_%s", key)))
}
return value
}
// otherwise nothing
return ""
}
97 changes: 97 additions & 0 deletions internal/generator/generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package generator

import (
"os"
"testing"

"github.com/uselagoon/build-deploy-tool/internal/helpers"
"github.com/uselagoon/build-deploy-tool/internal/lagoon"
)

func TestCheckFeatureFlag(t *testing.T) {
type args struct {
key string
envVariables []lagoon.EnvironmentVariable
debug bool
}
tests := []struct {
name string
vars []helpers.EnvironmentVariable
args args
want string
}{
{
name: "test1 - rootless from default",
vars: []helpers.EnvironmentVariable{
{
Name: "LAGOON_FEATURE_FLAG_DEFAULT_ROOTLESS_WORKLOAD",
Value: "enabled",
},
},
args: args{
key: "ROOTLESS_WORKLOAD",
},
want: "enabled",
},
{
name: "test2 - rootless from variable",
vars: []helpers.EnvironmentVariable{
{
Name: "LAGOON_FEATURE_FLAG_DEFAULT_ROOTLESS_WORKLOAD",
Value: "enabled",
},
},
args: args{
key: "ROOTLESS_WORKLOAD",
envVariables: []lagoon.EnvironmentVariable{
{
Name: "LAGOON_FEATURE_FLAG_ROOTLESS_WORKLOAD",
Value: "disabled",
Scope: "build",
},
},
},
want: "disabled",
},
{
name: "test2 - rootless from forced",
vars: []helpers.EnvironmentVariable{
{
Name: "LAGOON_FEATURE_FLAG_DEFAULT_ROOTLESS_WORKLOAD",
Value: "disabled",
},
{
Name: "LAGOON_FEATURE_FLAG_FORCE_ROOTLESS_WORKLOAD",
Value: "enabled",
},
},
args: args{
key: "ROOTLESS_WORKLOAD",
envVariables: []lagoon.EnvironmentVariable{
{
Name: "LAGOON_FEATURE_FLAG_ROOTLESS_WORKLOAD",
Value: "disabled",
Scope: "build",
},
},
},
want: "enabled",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for _, envVar := range tt.vars {
err := os.Setenv(envVar.Name, envVar.Value)
if err != nil {
t.Errorf("%v", err)
}
}
if got := CheckFeatureFlag(tt.args.key, tt.args.envVariables, tt.args.debug); got != tt.want {
t.Errorf("CheckFeatureFlag() = %v, want %v", got, tt.want)
}
t.Cleanup(func() {
helpers.UnsetEnvVars(tt.vars)
})
})
}
}
13 changes: 9 additions & 4 deletions internal/generator/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ func generateAutogenRoutes(
if lagoonYAML.Routes.Autogenerate.Insecure != "" {
insecure = lagoonYAML.Routes.Autogenerate.Insecure
}
ingressClass := buildValues.IngressClass
if lagoonYAML.Routes.Autogenerate.IngressClass != "" {
ingressClass = lagoonYAML.Routes.Autogenerate.IngressClass
}
autogenRoute := lagoon.RouteV2{
Domain: domain,
Fastly: *fastlyConfig,
Expand All @@ -178,6 +182,7 @@ func generateAutogenRoutes(
"lagoon.sh/service": serviceOverrideName,
"lagoon.sh/service-type": service.Type,
},
IngressClass: ingressClass,
Autogenerated: true,
LagoonService: serviceOverrideName,
ComposeService: serviceName,
Expand Down Expand Up @@ -248,7 +253,7 @@ func generateActiveStandbyRoutes(
if lagoonYAML.ProductionRoutes.Active != nil {
if lagoonYAML.ProductionRoutes.Active.Routes != nil {
for _, routeMap := range lagoonYAML.ProductionRoutes.Active.Routes {
lagoon.GenerateRoutesV2(activeStanbyRoutes, routeMap, envVars, buildValues.FastlyAPISecretPrefix, true)
lagoon.GenerateRoutesV2(activeStanbyRoutes, routeMap, envVars, buildValues.IngressClass, buildValues.FastlyAPISecretPrefix, true)
}
}
}
Expand All @@ -257,7 +262,7 @@ func generateActiveStandbyRoutes(
if lagoonYAML.ProductionRoutes.Standby != nil {
if lagoonYAML.ProductionRoutes.Standby.Routes != nil {
for _, routeMap := range lagoonYAML.ProductionRoutes.Standby.Routes {
lagoon.GenerateRoutesV2(activeStanbyRoutes, routeMap, envVars, buildValues.FastlyAPISecretPrefix, true)
lagoon.GenerateRoutesV2(activeStanbyRoutes, routeMap, envVars, buildValues.IngressClass, buildValues.FastlyAPISecretPrefix, true)
}
}
}
Expand Down Expand Up @@ -302,9 +307,9 @@ func generateAndMerge(

// otherwise it just uses the default environment name
for _, routeMap := range lagoonYAML.Environments[buildValues.Branch].Routes {
lagoon.GenerateRoutesV2(n, routeMap, envVars, buildValues.FastlyAPISecretPrefix, false)
lagoon.GenerateRoutesV2(n, routeMap, envVars, buildValues.IngressClass, buildValues.FastlyAPISecretPrefix, false)
}
// merge routes from the API on top of the routes from the `.lagoon.yml`
mainRoutes := lagoon.MergeRoutesV2(*n, api, envVars, buildValues.FastlyAPISecretPrefix)
mainRoutes := lagoon.MergeRoutesV2(*n, api, envVars, buildValues.IngressClass, buildValues.FastlyAPISecretPrefix)
return mainRoutes, nil
}
Loading

0 comments on commit b5537dc

Please sign in to comment.