Skip to content

Commit

Permalink
added bootstrapping export mode (#3649)
Browse files Browse the repository at this point in the history
* added export mode cli bootstrap

* rebased PR
  • Loading branch information
enekofb authored Dec 11, 2023
1 parent d27d52c commit bfc1a3f
Show file tree
Hide file tree
Showing 27 changed files with 583 additions and 126 deletions.
30 changes: 17 additions & 13 deletions cmd/gitops/app/bootstrap/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,25 @@ const (
- Authentication: check or setup cluster user authentication to access the dashboard.
`
cmdExamples = `
# Start WGE installation from the current kubeconfig
# Run Weave GitOps Enterprise bootstrapping in interactive session creating resources to the cluster and the Git repo.
gitops bootstrap
# Start WGE installation from a specific kubeconfig
gitops bootstrap --kubeconfig <your-kubeconfig-location>
# Run Weave GitOps Enterprise bootstrapping in non-interactive session. It uses values from flags and default values. It fails in case cannot complete the journey without asking the user.
gitops bootstrap --silent
# Start WGE installation with given admin 'password'
gitops bootstrap --password=hell0!
# Run Weave GitOps Enterprise bootstrapping in interactive session writing resources to stdout
gitops bootstrap --export > bootstrap-weave-gitops-enterprise.yaml
# Start WGE installation using OIDC
gitops bootstrap --client-id <client-id> --client-secret <client-secret> --discovery-url <discovery-url>
# Run Weave GitOps Enterprise bootstrapping from a specific Kubeconfig
gitops bootstrap --kubeconfig <your-kubeconfig-location>
# Start WGE installation with OIDC and flux bootstrap with https
gitops bootstrap --version=<version> --password=<admin-password> --discovery-url=<oidc-discovery-url> --client-id=<oidc-client-id> --git-username=<git-username-https> --gitPassword=<gitPassword> --bootstrap-flux --branch=<git-branch> --repo-path=<path-in-repo-for-management-cluster> --repo-url=https://<repo-url> --client-secret=<oidc-secret> -s
# Run Weave GitOps Enterprise bootstrapping with OIDC and Flux bootstrap with https
gitops bootstrap --silent --version=<version> --password=<admin-password> --discovery-url=<oidc-discovery-url> --client-id=<oidc-client-id> --client-secret=<oidc-secret> --git-username=<git-username-https> -gitPassword=<gitPassword>--branch=<git-branch> --repo-path=<path-in-repo-for-management-cluster> --repo-url=https://<repo-url>
# Start WGE installation with OIDC and flux bootstrap with ssh
gitops bootstrap --version=<version> --password=<admin-password> --discovery-url=<oidc-discovery-url> --client-id=<oidc-client-id> --private-key-path=<private-key-path> --private-key-password=<private-key-password> --branch=<git-branch> --repo-path=<path-in-repo-for-management-cluster> --repo-url=ssh://<repo-url> --client-secret=<oidc-secret> -s
# Run Weave GitOps Enterprise bootstrapping with OIDC and flux bootstrap with ssh
gitops bootstrap --silent --version=<version> --password=<admin-password> --discovery-url=<oidc-discovery-url> --client-id=<oidc-client-id> --client-secret=<oidc-secret> --private-key-path=<private-key-path> --private-key-password=<private-key-password> --branch=<git-branch> --repo-path=<path-in-repo-for-management-cluster> --repo-url=ssh://<repo-url>
# Start WGE installation with more than one extra controller
# Run Weave GitOps Enterprise bootstrapping with extra components
gitops bootstrap --components-extra="policy-agent,tf-controller"
`
)
Expand Down Expand Up @@ -68,6 +68,7 @@ type bootstrapFlags struct {

// modes flags
silent bool
export bool

// flux flag
bootstrapFlux bool
Expand Down Expand Up @@ -101,6 +102,7 @@ func Command(opts *config.Options) *cobra.Command {
cmd.PersistentFlags().StringVarP(&flags.discoveryURL, "discovery-url", "", "", "OIDC discovery URL")
cmd.PersistentFlags().StringVarP(&flags.clientID, "client-id", "i", "", "OIDC client ID")
cmd.PersistentFlags().StringVarP(&flags.clientSecret, "client-secret", "", "", "OIDC client secret")
cmd.PersistentFlags().BoolVar(&flags.export, "export", false, "write to stdout the bootstrapping manifests without writing in the cluster or Git. It requires Flux to be bootstrapped.")
cmd.AddCommand(AuthCommand(opts))

return cmd
Expand All @@ -125,9 +127,11 @@ func getBootstrapCmdRun(opts *config.Options) func(*cobra.Command, []string) err
flags.gitPassword,
).
WithOIDCConfig(flags.discoveryURL, flags.clientID, flags.clientSecret, true).
WithSilentFlag(flags.silent).
WithBootstrapFluxFlag(flags.bootstrapFlux).
WithComponentsExtra(flags.componentsExtra).
WithSilent(flags.silent).
WithExport(flags.export).
WithWriter(cmd.OutOrStdout()).
Build()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/gitops/app/bootstrap/cmd_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func getAuthCmdRun(opts *config.Options) func(*cobra.Command, []string) error {
flags.gitPassword,
).
WithOIDCConfig(flags.discoveryURL, flags.clientID, flags.clientSecret, false).
WithSilentFlag(flags.silent).
WithSilent(flags.silent).
Build()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion docs/cli/bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func TestAskAdminCredsSecretStep_Execute(t *testing.T) {
{
name: "should create cluster user non-interactive",
setup: func() (BootstrapStep, Config) {
config := makeTestConfig(t, Config{})
config := MakeTestConfig(t, Config{})
step, err := NewAskAdminCredsSecretStep(config.ClusterUserAuth, true)
assert.NoError(t, err)
return step, config
Expand Down
39 changes: 31 additions & 8 deletions pkg/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@ import (
// Bootstrap initiated by the command runs the WGE bootstrap workflow
func Bootstrap(config steps.Config) error {

adminCredentials, err := steps.NewAskAdminCredsSecretStep(config.ClusterUserAuth, config.Silent)
adminCredentials, err := steps.NewAskAdminCredsSecretStep(config.ClusterUserAuth, config.ModesConfig)
if err != nil {
return fmt.Errorf("cannot create ask admin creds step: %v", err)
}

repositoryConfig := steps.NewGitRepositoryConfigStep(config.GitRepository)

componentesExtra := steps.NewInstallExtraComponentsStep(config.ComponentsExtra, config.Silent)
checkUiDomain, err := steps.NewCheckUIDomainStep(config.ModesConfig)
if err != nil {
return fmt.Errorf("cannot create check ui: %v", err)
}

componentsExtra := steps.NewInstallExtraComponentsStep(config.ComponentsExtra, config.ModesConfig.Silent)

// TODO have a single workflow source of truth and documented in https://docs.gitops.weave.works/docs/0.33.0/enterprise/getting-started/install-enterprise/
var steps = []steps.BootstrapStep{
var workflow = []steps.BootstrapStep{
steps.VerifyFluxInstallation,
steps.NewAskBootstrapFluxStep(config),
repositoryConfig,
Expand All @@ -30,16 +35,34 @@ func Bootstrap(config steps.Config) error {
steps.NewInstallWGEStep(),
steps.NewInstallOIDCStep(config),
steps.NewOIDCConfigStep(config),
componentesExtra,
steps.CheckUIDomainStep,
componentsExtra,
checkUiDomain,
}

for _, step := range steps {
return execute(config, workflow)
}

func execute(config steps.Config, worfklow []steps.BootstrapStep) error {
var allOutputs []steps.StepOutput

for _, step := range worfklow {
config.Logger.Waitingf(step.Name)
_, err := step.Execute(&config)
stepOutputs, err := step.Execute(&config)
if err != nil {
return err
return fmt.Errorf("error on step %s: %v", step.Name, err)
}
allOutputs = append(allOutputs, stepOutputs...)
}

if config.ModesConfig.Export {
config.Logger.Actionf("export manifests")
for _, output := range allOutputs {
err := output.Export(config.Output)
if err != nil {
return fmt.Errorf("error exporting output %s: %v", output.Name, err)
}
}
}

return nil
}
38 changes: 38 additions & 0 deletions pkg/bootstrap/bootstrap_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package bootstrap

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"
. "github.com/weaveworks/weave-gitops-enterprise/pkg/bootstrap/steps"
)

func Test_executeSteps(t *testing.T) {

var buf bytes.Buffer

config := MakeTestConfig(t, Config{
Output: &buf,
ClusterUserAuth: ClusterUserAuthConfig{
Password: "password123",
},
ModesConfig: ModesConfig{
Silent: true,
Export: true,
},
})
clusterUserAuthStep, err := NewAskAdminCredsSecretStep(config.ClusterUserAuth, config.ModesConfig)
assert.NoError(t, err)

steps := []BootstrapStep{
clusterUserAuthStep,
}

t.Run("should support export", func(t *testing.T) {
err := execute(config, steps)
assert.NoError(t, err)
assert.Contains(t, buf.String(), "cluster-user-auth")
})

}
8 changes: 6 additions & 2 deletions pkg/bootstrap/steps/admin_password.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ func NewClusterUserAuthConfig(password string, client k8sclient.Client) (Cluster
// NewAskAdminCredsSecretStep asks user about admin password.
// Admin password are you used for accessing WGE Dashboard for emergency access.
// Users will be asked to continue with the current creds or overriding existing credentials during bootstrapping.
func NewAskAdminCredsSecretStep(config ClusterUserAuthConfig, silent bool) (BootstrapStep, error) {
func NewAskAdminCredsSecretStep(config ClusterUserAuthConfig, modes ModesConfig) (BootstrapStep, error) {
inputs := []StepInput{}
// UPDATE: this logic should return that `given a specific configuration when we want to aks the user`
// these are usually:
// interactive session that a) involves updates or b) creates that we require value
// non-interactive sessions should always take an action which in case of conflict should be the safest for the user
if !silent {
if !modes.Silent {
if !config.ExistCredentials {
if config.Password == "" {
inputs = append(inputs, createPasswordInput)
Expand Down Expand Up @@ -121,6 +121,10 @@ func createCredentials(input []StepInput, c *Config) ([]StepOutput, error) {
c.Logger.Actionf("dashboard admin username: %s is configured", defaultAdminUsername)

secret := corev1.Secret{
TypeMeta: v1.TypeMeta{
APIVersion: "v1",
Kind: "Secret",
},
ObjectMeta: v1.ObjectMeta{
Name: adminSecretName,
Namespace: WGEDefaultNamespace,
Expand Down
Loading

0 comments on commit bfc1a3f

Please sign in to comment.