Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cmd/template_autogen_ingress_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"encoding/base64"
"fmt"
"io/fs"
"os"
Expand Down Expand Up @@ -551,6 +552,44 @@ func TestAutogeneratedIngressGeneration(t *testing.T) {
templatePath: "testdata/output",
want: "internal/testdata/basic/autogen-templates/test29-autogenerated-pathroutes",
},
{
name: "autogenerated-routes-api-config-against-existing-reuslt",
args: testdata.GetSeedData(
testdata.TestData{
ProjectName: "example-project",
EnvironmentName: "main",
Branch: "main",
LagoonYAML: "internal/testdata/node/lagoon.yml",
ProjectVariables: []lagoon.EnvironmentVariable{
{
Name: "LAGOON_API_AUTOGENERATED_CONFIG",
Value: base64.URLEncoding.EncodeToString([]byte(`{"enabled":true,"allowPullRequests":true,"tlsAcme":true,"disableRequestVerification":false,"insecure":"Redirect","prefixes":[],"pathRoutes":[]}`)),
Scope: "internal_system",
},
},
}, true),
templatePath: "testoutput",
want: "internal/testdata/node/autogen-templates/ingress-1",
},
{
name: "autogenerated-routes-api-config",
args: testdata.GetSeedData(
testdata.TestData{
ProjectName: "example-project",
EnvironmentName: "main",
Branch: "main",
LagoonYAML: "internal/testdata/node/lagoon.yml",
ProjectVariables: []lagoon.EnvironmentVariable{
{
Name: "LAGOON_API_AUTOGENERATED_CONFIG",
Value: base64.URLEncoding.EncodeToString([]byte(`{"enabled":true,"allowPullRequests":true,"tlsAcme":true,"disableRequestVerification":false,"prefixes":["ie","de","abc"],"pathRoutes":[{"toService":"node","fromService":"node","path":"/"}],"insecure":"Redirect"}`)),
Scope: "internal_system",
},
},
}, true),
templatePath: "testoutput",
want: "internal/testdata/node/autogen-templates/autogenerated-routes-api-config",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
72 changes: 72 additions & 0 deletions cmd/template_ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,78 @@ func TestTemplateRoutes(t *testing.T) {
templatePath: "testoutput",
want: "internal/testdata/node/ingress-templates/ingress-24",
},
{
name: "active-standby-api-routes",
args: testdata.GetSeedData(
testdata.TestData{
ProjectName: "example-project",
EnvironmentName: "prod-left",
Branch: "prod-left",
LagoonYAML: "internal/testdata/node/lagoon.yml",
ProjectVariables: []lagoon.EnvironmentVariable{
{
Name: "LAGOON_API_ROUTES",
Value: base64.URLEncoding.EncodeToString([]byte(`{"routes":[
{"type":"ACTIVE", "domain":"active.example.com","service":"node","alternativeNames":[],"annotations":{},"pathRoutes":[],"tlsAcme":true,"insecure":"Redirect","hstsEnabled":false,"hstsIncludeSubdomains":false,"hstsPreload":false,"hstsMaxAge":3153600,"primary":false,"source":"API"},
{"domain":"other.example.com","service":"node","alternativeNames":[],"annotations":{},"pathRoutes":[],"tlsAcme":true,"insecure":"Redirect","hstsEnabled":false,"hstsIncludeSubdomains":false,"hstsPreload":false,"hstsMaxAge":3153600,"primary":false,"source":"API"},
{"domain":"test.example.com","service":"node","alternativeNames":[],"annotations":{},"pathRoutes":[],"tlsAcme":true,"insecure":"Redirect","hstsEnabled":false,"hstsIncludeSubdomains":false,"hstsPreload":false,"hstsMaxAge":3153600,"primary":true,"source":"API"}
]}`)),
Scope: "internal_system",
},
},
}, true),
templatePath: "testoutput",
want: "internal/testdata/node/ingress-templates/active-standby-api-routes",
},
{
name: "api-defined-routes-with-lagoon-yml",
args: testdata.GetSeedData(
testdata.TestData{
ProjectName: "example-project",
EnvironmentName: "main",
Branch: "main",
LagoonYAML: "internal/testdata/node/lagoon.yml",
ProjectVariables: []lagoon.EnvironmentVariable{
{
Name: "LAGOON_API_ROUTES",
Value: base64.URLEncoding.EncodeToString([]byte(`{"routes":[
{"domain":"other.example.com","service":"node","alternativeNames":[],"annotations":{},"pathRoutes":[],"tlsAcme":true,"insecure":"Redirect","hstsEnabled":false,"hstsIncludeSubdomains":false,"hstsPreload":false,"hstsMaxAge":3153600,"primary":false,"source":"API"},
{"domain":"test.example.com","service":"node","alternativeNames":[],"annotations":{},"pathRoutes":[],"tlsAcme":true,"insecure":"Redirect","hstsEnabled":false,"hstsIncludeSubdomains":false,"hstsPreload":false,"hstsMaxAge":3153600,"primary":true,"source":"API"}
]}`)),
Scope: "internal_system",
},
},
}, true),
templatePath: "testoutput",
want: "internal/testdata/node/ingress-templates/api-defined-routes-with-lagoon-yml",
},
{
name: "api-defined-routes-with-lagoon-yml-fastly",
args: testdata.GetSeedData(
testdata.TestData{
ProjectName: "example-project",
EnvironmentName: "main",
Branch: "main",
LagoonYAML: "internal/testdata/node/lagoon.yml",
ProjectVariables: []lagoon.EnvironmentVariable{
{
Name: "LAGOON_FASTLY_SERVICE_ID",
Value: "service-id:true",
Scope: "build",
},
{
Name: "LAGOON_API_ROUTES",
Value: base64.URLEncoding.EncodeToString([]byte(`{"routes":[
{"domain":"other.example.com","service":"node","alternativeNames":[],"annotations":{},"pathRoutes":[],"tlsAcme":true,"insecure":"Redirect","hstsEnabled":false,"hstsIncludeSubdomains":false,"hstsPreload":false,"hstsMaxAge":3153600,"primary":false,"source":"API"},
{"domain":"test.example.com","service":"node","alternativeNames":[],"annotations":{},"pathRoutes":[],"tlsAcme":true,"insecure":"Redirect","hstsEnabled":false,"hstsIncludeSubdomains":false,"hstsPreload":false,"hstsMaxAge":3153600,"primary":true,"source":"API"}
]}`)),
Scope: "internal_system",
},
},
}, true),
templatePath: "testoutput",
want: "internal/testdata/node/ingress-templates/api-defined-routes-with-lagoon-yml-fastly",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
6 changes: 4 additions & 2 deletions internal/collector/testdata/json-result/result-1.json
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,8 @@
"lagoon.sh/project": "example-project",
"lagoon.sh/service": "example.com",
"lagoon.sh/service-type": "custom-ingress",
"lagoon.sh/template": "custom-ingress-0.1.0"
"lagoon.sh/template": "custom-ingress-0.1.0",
"route.lagoon.sh/source": "yaml"
},
"annotations": {
"fastly.amazee.io/service-id": "service-id",
Expand Down Expand Up @@ -386,7 +387,8 @@
"lagoon.sh/project": "example-project",
"lagoon.sh/service": "node",
"lagoon.sh/service-type": "node",
"lagoon.sh/template": "autogenerated-ingress-0.1.0"
"lagoon.sh/template": "autogenerated-ingress-0.1.0",
"route.lagoon.sh/source": "autogenerated"
},
"annotations": {
"fastly.amazee.io/watch": "false",
Expand Down
6 changes: 4 additions & 2 deletions internal/collector/testdata/json-result/result-2.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@
"lagoon.sh/project": "example-project",
"lagoon.sh/service": "example.com",
"lagoon.sh/service-type": "custom-ingress",
"lagoon.sh/template": "custom-ingress-0.1.0"
"lagoon.sh/template": "custom-ingress-0.1.0",
"route.lagoon.sh/source": "yaml"
},
"annotations": {
"fastly.amazee.io/service-id": "service-id",
Expand Down Expand Up @@ -261,7 +262,8 @@
"lagoon.sh/project": "example-project",
"lagoon.sh/service": "node",
"lagoon.sh/service-type": "node",
"lagoon.sh/template": "autogenerated-ingress-0.1.0"
"lagoon.sh/template": "autogenerated-ingress-0.1.0",
"route.lagoon.sh/source": "autogenerated"
},
"annotations": {
"fastly.amazee.io/watch": "false",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ items:
lagoon.sh/service: example.com
lagoon.sh/service-type: custom-ingress
lagoon.sh/template: custom-ingress-0.1.0
route.lagoon.sh/source: yaml
name: example.com
namespace: example-project-main
resourceVersion: "1"
Expand Down Expand Up @@ -79,6 +80,7 @@ items:
lagoon.sh/service: node
lagoon.sh/service-type: node
lagoon.sh/template: autogenerated-ingress-0.1.0
route.lagoon.sh/source: autogenerated
name: node
namespace: example-project-main
resourceVersion: "1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ items:
lagoon.sh/service: example.com
lagoon.sh/service-type: custom-ingress
lagoon.sh/template: custom-ingress-0.1.0
route.lagoon.sh/source: yaml
name: example.com
namespace: example-project-main
resourceVersion: "1"
Expand Down Expand Up @@ -79,6 +80,7 @@ items:
lagoon.sh/service: node
lagoon.sh/service-type: node
lagoon.sh/template: autogenerated-ingress-0.1.0
route.lagoon.sh/source: autogenerated
name: node
namespace: example-project-main
resourceVersion: "1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ metadata:
lagoon.sh/service: example.com
lagoon.sh/service-type: custom-ingress
lagoon.sh/template: custom-ingress-0.1.0
route.lagoon.sh/source: yaml
name: example.com
spec:
rules:
Expand Down
1 change: 1 addition & 0 deletions internal/collector/testdata/seed/seed-1/ingress-node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ metadata:
lagoon.sh/service: node
lagoon.sh/service-type: node
lagoon.sh/template: autogenerated-ingress-0.1.0
route.lagoon.sh/source: autogenerated
name: node
spec:
rules:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ metadata:
lagoon.sh/service: example.com
lagoon.sh/service-type: custom-ingress
lagoon.sh/template: custom-ingress-0.1.0
route.lagoon.sh/source: yaml
name: example.com
spec:
rules:
Expand Down
1 change: 1 addition & 0 deletions internal/collector/testdata/seed/seed-2/ingress-node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ metadata:
lagoon.sh/service: node
lagoon.sh/service-type: node
lagoon.sh/template: autogenerated-ingress-0.1.0
route.lagoon.sh/source: autogenerated
name: node
spec:
rules:
Expand Down
27 changes: 27 additions & 0 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package generator

import (
"encoding/base64"
"encoding/json"
"fmt"
"net/url"
Expand Down Expand Up @@ -283,6 +284,32 @@ func NewGenerator(
buildValues.LagoonVersion = lagoonCoreVersion.Value
}

lagoonAutogeneratedRouteConfig, _ := lagoon.GetLagoonVariable("LAGOON_API_AUTOGENERATED_CONFIG", []string{"internal_system"}, buildValues.EnvironmentVariables)
if lagoonAutogeneratedRouteConfig != nil {
autogenConfig := &lagoon.Autogenerate{}
rawJSONStr, _ := base64.StdEncoding.DecodeString(lagoonAutogeneratedRouteConfig.Value)
rawJSON := []byte(rawJSONStr)
err := json.Unmarshal(rawJSON, autogenConfig)
if err != nil {
return nil, fmt.Errorf("couldn't unmarshal autogenerated route config from Lagoon API, is it actually JSON that has been base64 encoded?: %v", err)
}
environment := lagoon.Environment{}
if buildValues.LagoonYAML.Environments == nil {
buildValues.LagoonYAML.Environments = make(lagoon.Environments)
} else {
environment = buildValues.LagoonYAML.Environments[buildValues.Branch]
}
// replace the project autogenerated routes config with one from the api
// this replaces the entire configuration that would be defined in the .lagoon.yml file
// thus, the .lagoon.yml is ignored for the `routes.autogenerate` stanza and anything that might be defined for specific environments
// any api defined autogenerated route configurations
buildValues.LagoonYAML.Routes.Autogenerate = *autogenConfig
// overwrite the environment with the project values, autogenerated route config
environment.AutogeneratePathRoutes = autogenConfig.PathRoutes
environment.AutogenerateRoutes = autogenConfig.Enabled
buildValues.LagoonYAML.Environments[buildValues.Branch] = environment
}

// handle generating the container registry login generation here, extract from the `.lagoon.yml` firstly
if err := configureContainerRegistries(&buildValues); err != nil {
return nil, err
Expand Down
46 changes: 32 additions & 14 deletions internal/generator/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ func generateRoutes(
autogen = append(autogen, fmt.Sprintf("%s%s", prefix, autogenRoutes.Routes[i].Domain))
if i == 0 {
primary = fmt.Sprintf("%s%s", prefix, autogenRoutes.Routes[i].Domain)
// } else {
// remainders = append(remainders, fmt.Sprintf("%s%s", prefix, autogenRoutes.Routes[i].Domain))
}
remainders = append(remainders, fmt.Sprintf("%s%s", prefix, autogenRoutes.Routes[i].Domain))
for a := 0; a < len(autogenRoutes.Routes[i].AlternativeNames); a++ {
Expand All @@ -54,14 +52,20 @@ func generateRoutes(

// get the first route from the list of routes, replace the previous one if necessary
if len(mainRoutes.Routes) > 0 {
// if primary != "" {
// remainders = append(remainders, primary)
// }
apiPrimary := false
// first check of the routes for any api provided routes that may be marked as the `primary` route
for i := 0; i < len(mainRoutes.Routes); i++ {
if i == 0 {
// if any of the routes have the `Primary` flag set to true in the API
// handle setting it as the primary route
if mainRoutes.Routes[i].Primary != nil && *mainRoutes.Routes[i].Primary {
apiPrimary = true
primary = fmt.Sprintf("%s%s", prefix, mainRoutes.Routes[i].Domain)
}
}
// then second run through to determine the primary if an api primary was not found
for i := 0; i < len(mainRoutes.Routes); i++ {
if i == 0 && !apiPrimary {
primary = fmt.Sprintf("%s%s", prefix, mainRoutes.Routes[i].Domain)
// } else {
// remainders = append(remainders, fmt.Sprintf("%s%s", prefix, mainRoutes.Routes[i].Domain))
}
remainders = append(remainders, fmt.Sprintf("%s%s", prefix, mainRoutes.Routes[i].Domain))
for a := 0; a < len(mainRoutes.Routes[i].AlternativeNames); a++ {
Expand All @@ -81,17 +85,11 @@ func generateRoutes(
}
// get the first route from the list of routes, replace the previous one if necessary
if len(activeStanbyRoutes.Routes) > 0 {
// if primary != "" {
// remainders = append(remainders, primary)
// }
for i := 0; i < len(activeStanbyRoutes.Routes); i++ {
if i == 0 {
primary = fmt.Sprintf("%s%s", prefix, activeStanbyRoutes.Routes[i].Domain)
// } else {
// remainders = append(remainders, fmt.Sprintf("%s%s", prefix, activeStanbyRoutes.Routes[i].Domain))
}
remainders = append(remainders, fmt.Sprintf("%s%s", prefix, activeStanbyRoutes.Routes[i].Domain))
// remainders = append(remainders, fmt.Sprintf("%s%s", prefix, activeStanbyRoutes.Routes[i].Domain))
for a := 0; a < len(activeStanbyRoutes.Routes[i].AlternativeNames); a++ {
remainders = append(remainders, fmt.Sprintf("%s%s", prefix, activeStanbyRoutes.Routes[i].AlternativeNames[a]))
}
Expand Down Expand Up @@ -224,6 +222,8 @@ func generateAutogenRoutes(
AlternativeNames: alternativeNames,
RequestVerification: helpers.BoolPtr(service.AutogeneratedRoutesRequestVerification),
PathRoutes: pathRoutes,
// @TODO: eventually use machinery/schema instead of string
Source: "AUTOGENERATED",
}
autogenRoutes.Routes = append(autogenRoutes.Routes, autogenRoute)
}
Expand Down Expand Up @@ -319,17 +319,35 @@ func getRoutesFromAPIEnvVar(
) (*lagoon.RoutesV2, error) {
apiRoutes := &lagoon.RoutesV2{}
lagoonRoutesJSON, _ := lagoon.GetLagoonVariable("LAGOON_ROUTES_JSON", []string{"build", "global"}, envVars)
lagoonAPIRoutes, _ := lagoon.GetLagoonVariable("LAGOON_API_ROUTES", []string{"internal_system"}, envVars)
// if `LAGOON_ROUTES_JSON` is present, prefer it first to so not to break existing configurations
if lagoonRoutesJSON != nil {
if debug {
fmt.Println("Collecting routes from environment variable LAGOON_ROUTES_JSON")
}
if lagoonAPIRoutes != nil {
fmt.Println("Routes have also been defined in the API, these are ignored as LAGOON_ROUTES_JSON is configured. You should migrate all routes to the API.")
}
// if the routesJSON is populated, then attempt to decode and unmarshal it
rawJSONStr, _ := base64.StdEncoding.DecodeString(lagoonRoutesJSON.Value)
rawJSON := []byte(rawJSONStr)
err := json.Unmarshal(rawJSON, apiRoutes)
if err != nil {
return nil, fmt.Errorf("couldn't unmarshal routes from Lagoon API, is it actually JSON that has been base64 encoded?: %v", err)
}
} else {
if lagoonAPIRoutes != nil {
if debug {
fmt.Println("Collecting routes from environment variable LAGOON_API_ROUTES")
}
// if the routesJSON is populated, then attempt to decode and unmarshal it
rawJSONStr, _ := base64.StdEncoding.DecodeString(lagoonAPIRoutes.Value)
rawJSON := []byte(rawJSONStr)
err := json.Unmarshal(rawJSON, apiRoutes)
if err != nil {
return nil, fmt.Errorf("couldn't unmarshal routes from Lagoon API, is it actually JSON that has been base64 encoded?: %v", err)
}
}
}
return apiRoutes, nil
}
Expand Down
Loading
Loading