Skip to content

Commit

Permalink
BREAKING CHANGE! Update tyk-k8s-bootstrap configuration structure.
Browse files Browse the repository at this point in the history
Remove unused configuration parameters. Integrate `envconfig` library to
achieve consistent environment variable namings for all configuration
parameters.

Signed-off-by: Burak Sekili <buraksekili@gmail.com>
  • Loading branch information
buraksekili committed Nov 2, 2023
1 parent 52c5522 commit 192767b
Show file tree
Hide file tree
Showing 15 changed files with 179 additions and 215 deletions.
10 changes: 5 additions & 5 deletions cmd/bootstrap-post/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func main() {
err := data.InitAppDataPostInstall()
err := data.InitPostInstall()
if err != nil {
fmt.Println(err)
os.Exit(1)
Expand All @@ -24,7 +24,7 @@ func main() {
}

tp := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: data.AppConfig.DashboardInsecureSkipVerify},
TLSClientConfig: &tls.Config{InsecureSkipVerify: data.BootstrapConf.InsecureSkipVerify},
}
client := http.Client{Transport: tp}

Expand All @@ -45,7 +45,7 @@ func main() {
fmt.Println("Finished generating dashboard credentials")

fmt.Println("Started bootstrapping operator secret")
if data.AppConfig.OperatorSecretEnabled {
if data.BootstrapConf.OperatorKubernetesSecretName != "" {
err = helpers.BootstrapTykOperatorSecret()
if err != nil {
fmt.Println(err)
Expand All @@ -55,7 +55,7 @@ func main() {
fmt.Println("Finished bootstrapping operator secret")

fmt.Println("Started bootstrapping portal secret")
if data.AppConfig.DeveloperPortalSecretEnabled {
if data.BootstrapConf.DevPortalKubernetesSecretName != "" {
err = helpers.BootstrapTykPortalSecret()
if err != nil {
fmt.Println(err)
Expand All @@ -64,7 +64,7 @@ func main() {
}

fmt.Println("Started bootstrapping portal with requests to dashboard")
if data.AppConfig.BootstrapPortal {
if data.BootstrapConf.BootstrapPortal {
err = helpers.BoostrapPortal(client)
if err != nil {
fmt.Println(err)
Expand Down
2 changes: 1 addition & 1 deletion cmd/bootstrap-pre-delete/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func main() {
err := data.InitAppDataPreDelete()
err := data.InitBootstrapConf()
if err != nil {
fmt.Println(err)
os.Exit(1)
Expand Down
9 changes: 8 additions & 1 deletion cmd/bootstrap-pre-install/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ package main
import (
"fmt"
"os"
"tyk/tyk/bootstrap/data"
"tyk/tyk/bootstrap/preinstallation"
)

func main() {
err := preinstallation.PreHookInstall()
err := data.InitBootstrapConf()
if err != nil {
fmt.Printf("Failed to parse bootstrap environment variables, err: %v", err)
os.Exit(1)
}

err = preinstallation.PreHookInstall()
if err != nil {
fmt.Printf("Failed to run pre-hook job, err: %v", err)
os.Exit(1)
Expand Down
20 changes: 0 additions & 20 deletions constants/constants.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,6 @@
package constants

const (
OperatorSecretEnabledEnvVar = "OPERATOR_SECRET_ENABLED"
DeveloperPortalSecretEnabledEnvVar = "DEVELOPER_PORTAL_SECRET_ENABLED"
BootstrapPortalEnvVar = "BOOTSTRAP_PORTAL"
TykDashboardDeployEnvVar = "TYK_DASHBOARD_DEPLOY"
OperatorSecretNameEnvVar = "OPERATOR_SECRET_NAME"
DeveloperPortalSecretNameEnvVar = "DEVELOPER_PORTAL_SECRET_NAME"
TykAdminFirstNameEnvVar = "TYK_ADMIN_FIRST_NAME"
TykAdminLastNameEnvVar = "TYK_ADMIN_LAST_NAME"
TykAdminEmailEnvVar = "TYK_ADMIN_EMAIL"
TykAdminPasswordEnvVar = "TYK_ADMIN_PASSWORD"
TykPodNamespaceEnvVar = "TYK_POD_NAMESPACE"
TykDashboardProtoEnvVar = "TYK_DASHBOARD_PROTO"
TykDashboardInsecureSkipVerify = "TYK_DASHBOARD_INSECURE_SKIP_VERIFY"
TykDashboardLicenseEnvVarName = "TYK_DB_LICENSEKEY"
TykDbLicensekeyEnvVar = "TYK_DB_LICENSEKEY"
TykAdminSecretEnvVar = "TYK_ADMIN_SECRET"
DashboardEnabledEnvVar = "DASHBOARD_ENABLED"
TykOrgNameEnvVar = "TYK_ORG_NAME"
TykOrgCnameEnvVar = "TYK_ORG_CNAME"

TykBootstrapLabel = "tyk.tyk.io/k8s-bootstrap"
TykBootstrapPreDeleteLabel = "tyk-k8s-bootstrap-pre-delete"
TykBootstrapDashboardDeployLabel = "tyk-dashboard"
Expand Down
206 changes: 93 additions & 113 deletions data/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,147 +3,125 @@ package data
import (
"context"
"fmt"
"github.com/kelseyhightower/envconfig"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"os"
"strconv"
"tyk/tyk/bootstrap/constants"
)

type AppArguments struct {
DashboardHost string
DashboardPort int32
DashBoardLicense string
TykAdminSecret string
CurrentOrgName string
TykAdminPassword string
Cname string
TykAdminFirstName string
TykAdminLastName string
TykAdminEmailAddress string
UserAuth string
OrgId string
CatalogId string
DashboardUrl string
DashboardProto string
TykPodNamespace string
DashboardSvc string
DashboardInsecureSkipVerify bool
IsDashboardEnabled bool
OperatorSecretEnabled bool
OperatorSecretName string
DeveloperPortalSecretEnabled bool
DeveloperPortalSecretName string
BootstrapPortal bool
DashboardDeploymentName string
const prefix = "TYK_K8SBOOTSTRAP"

type Config struct {
// InsecureSkipVerify enables InsecureSkipVerify options in http request sent to Tyk - might be useful
// for Tyk Dashboard with self-signed certs.
InsecureSkipVerify bool
// BootstrapDashboard controls bootstrapping Tyk Dashboard or not.
BootstrapDashboard bool
// BootstrapPortal controls bootstrapping Tyk Classic Portal or not.
BootstrapPortal bool

// OperatorKubernetesSecretName corresponds to the Kubernetes secret name that will be created for Tyk Operator.
// Set it to an empty to string to disable bootstrapping Kubernetes secret for Tyk Operator.
// By default, tyk-operator-conf
OperatorKubernetesSecretName string
// DevPortalKubernetesSecretName corresponds to the Kubernetes secret name that will be created for
// Tyk Developer Enterprise Portal. Set it to an empty to string to disable bootstrapping Kubernetes
// secret for Tyk Developer Enterprise Portal.
// By default, tyk-dev-portal-conf
DevPortalKubernetesSecretName string
// K8s consists of configurations for Kubernetes services of Tyk.
K8s K8sConf
// Tyk consists of configurations for Tyk components such as Tyk Dashboard Admin information
// or Tyk Portal configurations.
Tyk TykConf
}

var AppConfig = AppArguments{
DashboardPort: 3000,
TykAdminSecret: "12345",
CurrentOrgName: "TYKTYK",
Cname: "tykCName",
TykAdminPassword: "123456",
TykAdminFirstName: "firstName",
TykAdminEmailAddress: "tyk@tyk.io",
TykAdminLastName: "lastName",
type K8sConf struct {
// DashboardSvcUrl corresponds to the URL of Tyk Dashboard.
DashboardSvcUrl string
// DashboardSvcProto corresponds to Tyk Dashboard Service Protocol (either http or https).
// By default, it is http.
DashboardSvcProto string
// ReleaseNamespace corresponds to the namespace where Tyk is deployed via Helm Chart.
ReleaseNamespace string
// DashboardDeploymentName corresponds to the name of the Tyk Dashboard Deployment, which is being used
// to restart Dashboard pod after bootstrapping. By default, it discovers Dashboard Deployment name.
// If the environment variable is populated, the discovery will not be triggered.
DashboardDeploymentName string
}

func InitAppDataPreDelete() error {
AppConfig.OperatorSecretName = os.Getenv(constants.OperatorSecretNameEnvVar)
AppConfig.DeveloperPortalSecretName = os.Getenv(constants.DeveloperPortalSecretNameEnvVar)
AppConfig.TykPodNamespace = os.Getenv(constants.TykPodNamespaceEnvVar)
return nil
type TykAdmin struct {
// Secret corresponds to the secret that will be used in Admin APIs.
Secret string
// FirstName corresponds to the first name of the admin being created.
FirstName string
// LastName corresponds to the last name of the admin being created.
LastName string
// EmailAddress corresponds to the email address of the admin being created.
EmailAddress string
// Password corresponds to the password of the admin being created.
Password string
}

func InitAppDataPostInstall() error {
AppConfig.TykAdminFirstName = os.Getenv(constants.TykAdminFirstNameEnvVar)
AppConfig.TykAdminLastName = os.Getenv(constants.TykAdminLastNameEnvVar)
AppConfig.TykAdminEmailAddress = os.Getenv(constants.TykAdminEmailEnvVar)
AppConfig.TykAdminPassword = os.Getenv(constants.TykAdminPasswordEnvVar)
AppConfig.TykPodNamespace = os.Getenv(constants.TykPodNamespaceEnvVar)
AppConfig.DashboardProto = os.Getenv(constants.TykDashboardProtoEnvVar)
type TykOrg struct {
// Name corresponds to the name for your organization that is going to be bootstrapped in Tyk
Name string
// Cname corresponds to the Organisation CNAME which is going to bind the Portal to.
Cname string
}

AppConfig.DashBoardLicense = os.Getenv(constants.TykDbLicensekeyEnvVar)
AppConfig.TykAdminSecret = os.Getenv(constants.TykAdminSecretEnvVar)
AppConfig.CurrentOrgName = os.Getenv(constants.TykOrgNameEnvVar)
AppConfig.Cname = os.Getenv(constants.TykOrgCnameEnvVar)
type TykConf struct {
// Admin consists of configurations for Tyk Dashboard Admin.
Admin TykAdmin
// Org consists of configurations for the organisation that is going to be created in Tyk Dashboard.
Org TykOrg

var err error
DashboardLicense string

dashEnabledRaw := os.Getenv(constants.DashboardEnabledEnvVar)
if dashEnabledRaw != "" {
AppConfig.IsDashboardEnabled, err = strconv.ParseBool(os.Getenv(constants.DashboardEnabledEnvVar))
if err != nil {
return fmt.Errorf("failed to parse %v, err: %v", constants.DashboardEnabledEnvVar, err)
}
}

if AppConfig.IsDashboardEnabled {
if err := discoverDashboardSvc(); err != nil {
return err
}
AppConfig.DashboardUrl = fmt.Sprintf("%s://%s.%s.svc.cluster.local:%d",
AppConfig.DashboardProto,
AppConfig.DashboardSvc,
AppConfig.TykPodNamespace,
AppConfig.DashboardPort,
)
}
// UserAuth corresponds to AuthCode of the created user, and it will be used in Authorization header
// of the HTTP requests that will be sent to Tyk for bootstrapping. Also, if bootstrapping Operator Secret
// is enabled via TODO: add here, UserAuth corresponds to TykAuth field in the Kubernetes secret for Tyk Operator.
UserAuth string `ignored:"true"`
OrgId string `ignored:"true"`
}

operatorSecretEnabledRaw := os.Getenv(constants.OperatorSecretEnabledEnvVar)
if operatorSecretEnabledRaw != "" {
AppConfig.OperatorSecretEnabled, err = strconv.ParseBool(operatorSecretEnabledRaw)
if err != nil {
return fmt.Errorf("failed to parse %v, err: %v", constants.OperatorSecretEnabledEnvVar, err)
}
}
var BootstrapConf = Config{}

AppConfig.OperatorSecretName = os.Getenv(constants.OperatorSecretNameEnvVar)
func InitBootstrapConf() error {
return envconfig.Process(prefix, &BootstrapConf)
}

developerPortalSecretEnabledRaw := os.Getenv(constants.DeveloperPortalSecretEnabledEnvVar)
if developerPortalSecretEnabledRaw != "" {
AppConfig.DeveloperPortalSecretEnabled, err = strconv.ParseBool(developerPortalSecretEnabledRaw)
if err != nil {
return err
}
func InitPostInstall() error {
err := InitBootstrapConf()
if err != nil {
return err
}
AppConfig.DeveloperPortalSecretName = os.Getenv(constants.DeveloperPortalSecretNameEnvVar)

bootstrapPortalBoolRaw := os.Getenv(constants.BootstrapPortalEnvVar)
if bootstrapPortalBoolRaw != "" {
AppConfig.BootstrapPortal, err = strconv.ParseBool(bootstrapPortalBoolRaw)
if BootstrapConf.BootstrapDashboard {
dashURL, err := discoverDashboardSvc()
if err != nil {
return fmt.Errorf("failed to parse %v, err: %v", constants.BootstrapPortalEnvVar, err)
return err
}
}
AppConfig.DashboardDeploymentName = os.Getenv(constants.TykDashboardDeployEnvVar)

dashboardInsecureSkipVerifyRaw := os.Getenv(constants.TykDashboardInsecureSkipVerify)
if dashboardInsecureSkipVerifyRaw != "" {
AppConfig.DashboardInsecureSkipVerify, err = strconv.ParseBool(dashboardInsecureSkipVerifyRaw)
if err != nil {
return fmt.Errorf("failed to parse %v, err: %v", constants.TykDashboardInsecureSkipVerify, err)
}
BootstrapConf.K8s.DashboardSvcUrl = dashURL
}

return nil
}

// discoverDashboardSvc lists Service objects with constants.TykBootstrapReleaseLabel label that has
// constants.TykBootstrapDashboardSvcLabel value and gets this Service's metadata name, and port and
// updates DashboardSvc and DashboardPort fields.
func discoverDashboardSvc() error {
// constants.TykBootstrapDashboardSvcLabel value and returns a service URL for Tyk Dashboard.
func discoverDashboardSvc() (string, error) {
config, err := rest.InClusterConfig()
if err != nil {
return err
return "", err
}

c, err := kubernetes.NewForConfig(config)
if err != nil {
return err
return "", err
}

ls := metav1.LabelSelector{MatchLabels: map[string]string{
Expand All @@ -154,14 +132,14 @@ func discoverDashboardSvc() error {

services, err := c.
CoreV1().
Services(AppConfig.TykPodNamespace).
Services(BootstrapConf.K8s.ReleaseNamespace).
List(context.TODO(), metav1.ListOptions{LabelSelector: l})
if err != nil {
return err
return "", err
}

if len(services.Items) == 0 {
return fmt.Errorf("failed to find services with label %v\n", l)
return "", fmt.Errorf("failed to find services with label %v\n", l)
}

if len(services.Items) > 1 {
Expand All @@ -170,14 +148,16 @@ func discoverDashboardSvc() error {

service := services.Items[0]
if len(service.Spec.Ports) == 0 {
return fmt.Errorf("svc/%v/%v has no open ports\n", service.Name, service.Namespace)
return "", fmt.Errorf("svc/%v/%v has no open ports\n", service.Name, service.Namespace)
}
if len(service.Spec.Ports) > 1 {
fmt.Printf("[WARNING] Found multiple open ports in svc/%v/%v\n", service.Name, service.Namespace)
}

AppConfig.DashboardPort = service.Spec.Ports[0].Port
AppConfig.DashboardSvc = service.Name

return nil
return fmt.Sprintf("%s://%s.%s.svc.cluster.local:%d",
BootstrapConf.K8s.DashboardSvcProto,
service.Name,
BootstrapConf.K8s.ReleaseNamespace,
service.Spec.Ports[0].Port,
), nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
github.com/google/gofuzz v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand Down
Loading

0 comments on commit 192767b

Please sign in to comment.