-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Onboarding CLI | Flux bootstrapping and git authentication credentials #3578
Changes from 2 commits
b8425e6
7e4fd03
118c73e
006f45a
da28aa8
80667a4
65dfcf2
0b27797
5e4d52b
7faee99
e3cc8a9
f58abae
b6f1064
51355a3
49d284a
03879c0
1395ede
c9b4477
c3dfb5c
0059abb
0ed19ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,9 +43,21 @@ type bootstrapFlags struct { | |
domainType string | ||
domain string | ||
|
||
// private key flags | ||
// git auth type | ||
gitAuthType string | ||
|
||
// private key (ssh-auth) flags | ||
privateKeyPath string | ||
privateKeyPassword string | ||
sshRepoURL string | ||
|
||
// https git auth flags | ||
gitUsername string | ||
gitToken string | ||
httpsRepoURL string | ||
|
||
branch string | ||
repoPath string | ||
|
||
// oidc flags | ||
discoveryURL string | ||
|
@@ -67,6 +79,13 @@ func Command(opts *config.Options) *cobra.Command { | |
cmd.Flags().StringVarP(&flags.domainType, "domain-type", "t", "", "dashboard domain type: could be 'localhost' or 'externaldns'") | ||
cmd.Flags().StringVarP(&flags.domain, "domain", "d", "", "indicate the domain to use in case of using `externaldns`") | ||
cmd.Flags().StringVarP(&flags.version, "version", "v", "", "version of Weave GitOps Enterprise (should be from the latest 3 versions)") | ||
cmd.PersistentFlags().StringVarP(&flags.gitAuthType, "git-auth-type", "g", "", "git authentication type. choose between (ssh, https)") | ||
cmd.PersistentFlags().StringVarP(&flags.gitUsername, "git-username", "", "", "git username used in https authentication type") | ||
cmd.PersistentFlags().StringVarP(&flags.gitToken, "git-token", "", "", "git token used in https authentication type") | ||
cmd.PersistentFlags().StringVarP(&flags.branch, "git-branch", "b", "", "git branch for your flux repository (example: main)") | ||
cmd.PersistentFlags().StringVarP(&flags.repoPath, "git-repo-path", "r", "", "git path for your flux repository (example: clusters/my-cluster)") | ||
cmd.PersistentFlags().StringVarP(&flags.sshRepoURL, "ssh-repo-url", "", "", "ssh git url for you flux repository (example: ssh://[email protected]/my-org-name/my-repo-name)") | ||
cmd.PersistentFlags().StringVarP(&flags.sshRepoURL, "https-repo-url", "", "", "https git url for you flux repository (example: https://github.com/my-org-name/my-repo-name)") | ||
enekofb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
cmd.PersistentFlags().StringVarP(&flags.privateKeyPath, "private-key", "k", "", "private key path. This key will be used to push the Weave GitOps Enterprise's resources to the default cluster repository") | ||
cmd.PersistentFlags().StringVarP(&flags.privateKeyPassword, "private-key-password", "c", "", "private key password. If the private key is encrypted using password") | ||
cmd.PersistentFlags().StringVarP(&flags.discoveryURL, "discovery-url", "", "", "OIDC discovery URL") | ||
|
@@ -92,7 +111,16 @@ func getBootstrapCmdRun(opts *config.Options) func(*cobra.Command, []string) err | |
WithVersion(flags.version). | ||
WithDomainType(flags.domainType). | ||
WithDomain(flags.domain). | ||
WithPrivateKey(flags.privateKeyPath, flags.privateKeyPassword). | ||
WithGitAuthentication(flags.gitAuthType, | ||
flags.privateKeyPath, | ||
flags.privateKeyPassword, | ||
flags.sshRepoURL, | ||
flags.httpsRepoURL, | ||
flags.gitUsername, | ||
flags.gitToken, | ||
flags.branch, | ||
flags.repoPath, | ||
). | ||
WithOIDCConfig(flags.discoveryURL, flags.clientID, flags.clientSecret, true). | ||
Build() | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,8 +9,11 @@ func Bootstrap(config steps.Config) error { | |
// 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{ | ||
steps.VerifyFluxInstallation, | ||
steps.NewAskBootstrapFluxStep(config), | ||
steps.NewSelectGitAuthType(config), | ||
steps.NewBootstrapFluxUsingSSH(config), | ||
steps.NewBootstrapFluxUsingHTTPS(config), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please share the design considerations used for selecting using these steps over other design like having a single step called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated to be steps.NewAskBootstrapFluxStep(config),
steps.NewFluxGitRepositoryConfig(config),
steps.NewBootstrapFlux(config), the currently implemented logic, process all the inputs first, then execute the step function for example in case of passing a repo-url with ssh scheme, we need to only ask about private key and private key password and in case of passing a repo-url with https scheme, then we need to ask about username and token and since we handle input first, then process, then out. if we don't pass the value to this step it'll ask all of them anyway |
||
steps.CheckEntitlementSecret, | ||
steps.NewAskPrivateKeyStep(config), | ||
steps.NewSelectWgeVersionStep(config), | ||
steps.NewAskAdminCredsSecretStep(config), | ||
steps.NewSelectDomainType(config), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package steps | ||
|
||
import "fmt" | ||
|
||
const ( | ||
bootstrapFluxMsg = "do you want to bootstrap flux using the generic way" | ||
) | ||
|
||
var ( | ||
bootstrapFLuxQuestion = StepInput{ | ||
Name: bootstrapFlux, | ||
Type: confirmInput, | ||
Msg: bootstrapFluxMsg, | ||
Enabled: canAskForGitConfig, | ||
} | ||
) | ||
|
||
func NewAskBootstrapFluxStep(config Config) BootstrapStep { | ||
return BootstrapStep{ | ||
Name: "bootstrap flux", | ||
Input: []StepInput{ | ||
bootstrapFLuxQuestion, | ||
}, | ||
Step: askBootstrapFlux, | ||
} | ||
} | ||
|
||
func askBootstrapFlux(input []StepInput, c *Config) ([]StepOutput, error) { | ||
if !canAskForGitConfig(input, c) { | ||
return []StepOutput{}, nil | ||
} | ||
for _, param := range input { | ||
if param.Name == bootstrapFlux { | ||
fluxBootstrapRes, ok := param.Value.(string) | ||
if ok { | ||
if fluxBootstrapRes != "y" { | ||
return []StepOutput{}, fmt.Errorf("flux bootstrapped error: %s", fluxRecoverMsg) | ||
} | ||
|
||
} | ||
} | ||
} | ||
return []StepOutput{}, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package steps | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/weaveworks/weave-gitops/pkg/runner" | ||
) | ||
|
||
const ( | ||
// https authentication | ||
gitHttpsRepoURLMsg = "please enter your git repository url (example: https://github.com/my-org-name/my-repo-name)" | ||
gitUserNameMsg = "please enter your git username" | ||
gitTokenMsg = "please enter your git authentication token with valid creds" | ||
) | ||
|
||
const ( | ||
httpsAuthStepName = "git https config" | ||
) | ||
|
||
var ( | ||
getHttpsRepoURL = StepInput{ | ||
Name: httpsRepoURL, | ||
Type: stringInput, | ||
Msg: gitHttpsRepoURLMsg, | ||
DefaultValue: "", | ||
Enabled: canAskForHttpsGitConfig, | ||
} | ||
|
||
getHttpsRepoBranch = StepInput{ | ||
Name: branch, | ||
Type: stringInput, | ||
Msg: gitRepoBranchMsg, | ||
DefaultValue: defaultBranch, | ||
Enabled: canAskForHttpsGitConfig, | ||
} | ||
|
||
getHttpsRepoPath = StepInput{ | ||
Name: repoPath, | ||
Type: stringInput, | ||
Msg: gitRepoPathMsg, | ||
DefaultValue: defaultPath, | ||
Enabled: canAskForHttpsGitConfig, | ||
} | ||
|
||
getGitUsername = StepInput{ | ||
Name: UserName, | ||
Type: stringInput, | ||
Msg: gitUserNameMsg, | ||
DefaultValue: "", | ||
Enabled: canAskForHttpsGitCreds, | ||
} | ||
|
||
getGitToken = StepInput{ | ||
Name: gitToken, | ||
Type: passwordInput, | ||
Msg: gitTokenMsg, | ||
DefaultValue: "", | ||
Enabled: canAskForHttpsGitCreds, | ||
Required: true, | ||
} | ||
) | ||
|
||
// NewBootstrapFluxUsingHTTPS step to bootstrap flux and configuring git using https | ||
func NewBootstrapFluxUsingHTTPS(config Config) BootstrapStep { | ||
// create steps | ||
inputs := []StepInput{} | ||
if config.HttpsRepoURL == "" { | ||
inputs = append(inputs, getHttpsRepoURL) | ||
} | ||
|
||
if config.Branch == "" { | ||
inputs = append(inputs, getHttpsRepoBranch) | ||
} | ||
|
||
if config.RepoPath == "" { | ||
inputs = append(inputs, getHttpsRepoPath) | ||
} | ||
|
||
if config.GitUsername == "" { | ||
inputs = append(inputs, getGitUsername) | ||
} | ||
if config.GitToken == "" { | ||
inputs = append(inputs, getGitToken) | ||
} | ||
|
||
return BootstrapStep{ | ||
Name: httpsAuthStepName, | ||
Input: inputs, | ||
Step: createGitHttpsConfig, | ||
} | ||
} | ||
|
||
func createGitHttpsConfig(input []StepInput, c *Config) ([]StepOutput, error) { | ||
for _, param := range input { | ||
if param.Name == httpsRepoURL { | ||
repoURL, ok := param.Value.(string) | ||
if ok { | ||
c.HttpsRepoURL = repoURL | ||
} | ||
} | ||
if param.Name == branch { | ||
repoBranch, ok := param.Value.(string) | ||
if ok { | ||
c.Branch = repoBranch | ||
} | ||
} | ||
|
||
if param.Name == repoPath { | ||
path, ok := param.Value.(string) | ||
if ok { | ||
c.RepoPath = path | ||
} | ||
} | ||
|
||
if param.Name == gitUserName { | ||
username, ok := param.Value.(string) | ||
if ok { | ||
c.GitUsername = username | ||
} | ||
} | ||
|
||
if param.Name == gitToken { | ||
token, ok := param.Value.(string) | ||
if ok { | ||
c.GitToken = token | ||
} | ||
} | ||
} | ||
if !canAskForHttpsGitConfig(input, c) { | ||
return []StepOutput{}, nil | ||
} | ||
c.Logger.Waitingf("bootstrapping flux ...") | ||
err := bootstrapFluxHttps(c) | ||
if err != nil { | ||
return []StepOutput{}, fmt.Errorf("failed to bootstrap flux: %v", err) | ||
} | ||
|
||
return []StepOutput{}, nil | ||
} | ||
|
||
func bootstrapFluxHttps(c *Config) error { | ||
var runner runner.CLIRunner | ||
out, err := runner.Run("flux", | ||
"bootstrap", | ||
"git", | ||
"--url", c.HttpsRepoURL, | ||
"--branch", c.Branch, | ||
"--path", c.RepoPath, | ||
"--username", c.GitUsername, | ||
"--password", c.GitToken, | ||
"--token-auth", "true", | ||
"-s", | ||
) | ||
|
||
if err != nil { | ||
return fmt.Errorf("%v:%v", err, string(out)) | ||
} | ||
c.Logger.Successf("successfully bootstrapped flux!") | ||
return nil | ||
} | ||
|
||
// canAskForHttpsGitConfig check when ask for gitconfig | ||
func canAskForHttpsGitConfig(input []StepInput, c *Config) bool { | ||
if !c.FluxInstallated { | ||
return c.GitAuthType == httpsAuthType | ||
} | ||
return false | ||
} | ||
|
||
// canAskForHttpsGitCreds check when ask for gitconfig | ||
func canAskForHttpsGitCreds(input []StepInput, c *Config) bool { | ||
return c.GitAuthType == httpsAuthType | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be token or password? i could see https://fluxcd.io/flux/cmd/flux_bootstrap_git/ is password
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah in flux is password but it's very confusing as adding the git https basic auth with password doesn't work anymore and only accept token
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes but i think that flux gets it from http where basic auth is username and password https://en.wikipedia.org/wiki/Basic_access_authentication
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but auth with username and password is no longer accepted https://docs.github.com/en/rest/overview/authenticating-to-the-rest-api?apiVersion=2022-11-28#authenticating-with-username-and-password
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahh we add
--token-auth
to flux configuration so that it can handle it as a tokenThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess flux is correct calling it password
https://fluxcd.io/flux/components/source/gitrepositories/#basic-access-authentication
as it is how is defined in the standard https://datatracker.ietf.org/doc/html/rfc7617#section-2
we could review this in the catchup too