Skip to content
This repository has been archived by the owner on Nov 11, 2020. It is now read-only.

Commit

Permalink
Merge pull request #30 from jstrachan/changes
Browse files Browse the repository at this point in the history
fix: improve CLI handling
  • Loading branch information
jstrachan authored Mar 11, 2020
2 parents 1905e0d + 968875c commit dc76540
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 89 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/heptio/sonobuoy v0.16.0
github.com/jenkins-x/go-scm v1.5.76
github.com/jenkins-x/golang-jenkins v0.0.0-20180919102630-65b83ad42314
github.com/jenkins-x/jx v0.0.0-20200310115539-b64ed22fb7af
github.com/jenkins-x/jx v0.0.0-20200311114321-719da6f179ca
github.com/jetstack/cert-manager v0.5.2
github.com/knative/serving v0.7.0
github.com/mitchellh/go-homedir v1.1.0
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k
github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/distribution v0.0.0-20170726174610-edc3ab29cdff/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.0.0-20171206114025-5e5fadb3c020 h1:aiKCZxnxoraZKXbM2zJj0ZI1n8eamkdK7zNxP7jlbII=
github.com/docker/docker v0.0.0-20171206114025-5e5fadb3c020/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o=
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
Expand Down Expand Up @@ -432,8 +433,8 @@ github.com/jenkins-x/go-scm v1.5.76 h1:IMlfD8K+XieU2rvA8Sp2fz6FejhFo6JuUG/Do1SZ9
github.com/jenkins-x/go-scm v1.5.76/go.mod h1:PCT338UhP/pQ0IeEeMEf/hoLTYKcH7qjGEKd7jPkeYg=
github.com/jenkins-x/golang-jenkins v0.0.0-20180919102630-65b83ad42314 h1:kyBMx/ucSV92S+umX/V6DDaPNynlFFOM9MGJWApltoU=
github.com/jenkins-x/golang-jenkins v0.0.0-20180919102630-65b83ad42314/go.mod h1:C6j5HgwlHGjRU27W4XCs6jXksqYFo8OdBu+p44jqQeM=
github.com/jenkins-x/jx v0.0.0-20200310115539-b64ed22fb7af h1:0m9oO/2JTQU3C2FQ62+CLHOm+uUlAuOEiLd/Nh8EAWA=
github.com/jenkins-x/jx v0.0.0-20200310115539-b64ed22fb7af/go.mod h1:QZVsigjVZ634iK2TqkIs10yANye4JbBF2bHd3i41U8o=
github.com/jenkins-x/jx v0.0.0-20200311114321-719da6f179ca h1:nS/m/akMwuKR95E3ZVzWgqkbWStsf0tPhWELUDQ2Mn4=
github.com/jenkins-x/jx v0.0.0-20200311114321-719da6f179ca/go.mod h1:QZVsigjVZ634iK2TqkIs10yANye4JbBF2bHd3i41U8o=
github.com/jetstack/cert-manager v0.5.2 h1:qs74mdAprZ5kcCYF3arzmEAZtbt+9HneldSJrk21tKs=
github.com/jetstack/cert-manager v0.5.2/go.mod h1:nbddmhjWxYGt04bxvwVGUSeLhZ2PCyNvd7MpXdq+yWY=
github.com/jinzhu/gorm v0.0.0-20170316141641-572d0a0ab1eb/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
Expand Down
5 changes: 5 additions & 0 deletions pkg/cmd/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ func (o *CreateOptions) Run() error {
return errors.Wrapf(err, "failed to override requirements in dir %s", dir)
}

_, _, err = reqhelpers.ValidateApps(dir)
if err != nil {
return errors.Wrapf(err, "failed to validate the apps based on requirements in dir %s", dir)
}

err = o.EnvFactory.VerifyPreInstall(o.DisableVerifyPackages, dir)
if err != nil {
return errors.Wrapf(err, "failed to verify requirements in dir %s", dir)
Expand Down
67 changes: 60 additions & 7 deletions pkg/cmd/create/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,20 @@ func TestCreate(t *testing.T) {
}
testCases := []testCase{
{
Name: "defaultcluster",
Name: "remote",
Args: []string{"--provider", "kubernetes", "--env-git-public", "--git-public", "--env-remote"},
},
{
Name: "bucketrepo",
Args: []string{"--provider", "kind", "--env-git-public", "--git-public", "--repository", "bucketrepo"},
},
{
Name: "tls",
Args: []string{"--provider", "kind", "--env-git-public", "--git-public", "--tls", "--externaldns"},
},
{
Name: "tls-custom-secret",
Args: []string{"--provider", "kind", "--env-git-public", "--git-public", "--tls", "--tls-secret", "my-tls-secret"},
},
}

Expand All @@ -37,7 +50,7 @@ func TestCreate(t *testing.T) {
outFile, err := ioutil.TempFile("", "")
require.NoError(t, err, "failed to create tempo file")
outFileName := outFile.Name()
args := []string{"--provider", "kubernetes", "--cluster", tc.Name, "--git-server", "https://fake.com", "--git-kind", "fake", "--env-git-owner", "jstrachan", "--out", outFileName, "--env-git-public", "--git-public", "--env-remote"}
args := append(tc.Args, "--git-server", "https://fake.com", "--git-kind", "fake", "--env-git-owner", "jstrachan", "--cluster", tc.Name, "--out", outFileName)
args = append(args, tc.Args...)
co.Args = args
co.JXFactory = fakejxfactory.NewFakeFactory()
Expand All @@ -64,6 +77,27 @@ func TestCreate(t *testing.T) {

AssertHasApp(t, apps, "jenkins-x/lighthouse", appMessage)

switch tc.Name {
case "remote":
AssertHasApp(t, apps, "jenkins-x/chartmuseum", appMessage)
AssertHasApp(t, apps, "jenkins-x/nexus", appMessage)
AssertHasApp(t, apps, "repositories", appMessage)
AssertNoApp(t, apps, "jenkins-x/bucketrepo", appMessage)

case "bucketrepo":
AssertHasApp(t, apps, "jenkins-x/bucketrepo", appMessage)
AssertHasApp(t, apps, "repositories", appMessage)
AssertNoApp(t, apps, "jenkins-x/chartmuseum", appMessage)
AssertNoApp(t, apps, "jenkins-x/nexus", appMessage)

case "tls":
AssertHasApp(t, apps, "jetstack/cert-manager", appMessage)
AssertHasApp(t, apps, "bitnami/externaldns", appMessage)

case "tls-custom-secret":
AssertNoApp(t, apps, "jetstack/cert-manager", appMessage)
AssertNoApp(t, apps, "bitnami/externaldns", appMessage)
}
assert.FileExists(t, outFileName, "did not generate the Git URL file")
data, err := ioutil.ReadFile(outFileName)
require.NoError(t, err, "failed to load file %s", outFileName)
Expand All @@ -80,14 +114,36 @@ func TestCreate(t *testing.T) {
if e.Key == "dev" {
assert.Equal(t, false, e.RemoteCluster, "requirements.Environments[%d].RemoteCluster for key %s", i, e.Key)
} else {
assert.Equal(t, true, e.RemoteCluster, "requirements.Environments[%d].RemoteCluster for key %s", i, e.Key)
expectedRemote := tc.Name == "remote"
assert.Equal(t, expectedRemote, e.RemoteCluster, "requirements.Environments[%d].RemoteCluster for key %s", i, e.Key)
}
t.Logf("requirements.Environments[%d].RemoteCluster = %v for key %s ", i, e.RemoteCluster, e.Key)
}

if requirements.Cluster.Provider == "kind" {
assert.Equal(t, true, requirements.Ingress.IgnoreLoadBalancer, "dev requirements.Ingress.IgnoreLoadBalancer for test %s", tc.Name)
}
}
}

// AssertHasApp asserts that the given app name is in the generated apps YAML
func AssertHasApp(t *testing.T, appConfig *config.AppConfig, appName string, message string) {
found, names := HasApp(t, appConfig, appName, message)
if !found {
assert.Fail(t, fmt.Sprintf("does not have the app %s for %s. Current apps are: %s", appName, message, strings.Join(names, ", ")))
}
}

// AssertNoApp asserts that the given app name is in the generated apps YAML
func AssertNoApp(t *testing.T, appConfig *config.AppConfig, appName string, message string) {
found, names := HasApp(t, appConfig, appName, message)
if found {
assert.Fail(t, fmt.Sprintf("should not have the app %s for %s. Current apps are: %s", appName, message, strings.Join(names, ", ")))
}
}

// HasApp tests that the app config has the given app
func HasApp(t *testing.T, appConfig *config.AppConfig, appName string, message string) (bool, []string) {
found := false
names := []string{}
for _, app := range appConfig.Apps {
Expand All @@ -97,8 +153,5 @@ func AssertHasApp(t *testing.T, appConfig *config.AppConfig, appName string, mes
found = true
}
}
if !found {
assert.Fail(t, fmt.Sprintf("does not have the app %s for %s. Current apps are: %s", appName, message, strings.Join(names, ", ")))
}

return found, names
}
8 changes: 3 additions & 5 deletions pkg/cmd/upgrade/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,16 @@ var (
// UpgradeOptions the options for upgrading a cluster
type UpgradeOptions struct {
envfactory.EnvFactory
NoCommit bool

OverrideRequirements config.RequirementsConfig
Namespace string
GitCloneURL string
InitialGitURL string
Dir string
UsePullRequest bool

// if we are modifing an existing git repository
gitRepositoryExisted bool
branchName string
UsePullRequest bool
NoCommit bool
gitRepositoryExisted bool // if we are modifying an existing git repository
}

// NewCmdUpgrade creates a command object for the command
Expand Down
6 changes: 5 additions & 1 deletion pkg/envfactory/env_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ type EnvFactory struct {
IOFileHandles *util.IOFileHandles
ScmClient *scm.Client
BatchMode bool
NoOAuth bool
}

// AddFlags adds common CLI flags
func (o *EnvFactory) AddFlags(cmd *cobra.Command) {
cmd.Flags().BoolVarP(&o.BatchMode, "batch-mode", "b", false, "Enables batch mode which avoids prompting for user input")
cmd.Flags().BoolVarP(&o.NoOAuth, "no-oauth", "", false, "Disables the use of OAuth login to github.com to get a github access token")
cmd.Flags().StringVarP(&o.RepoName, "repo", "", "", "the name of the development git repository to create")
cmd.Flags().StringVarP(&o.GitURLOutFile, "out", "", "", "the name of the file to save with the created git URL inside")

Expand Down Expand Up @@ -153,5 +155,7 @@ func (o *EnvFactory) PushToGit(cloneURL string, userAuth *auth.UserAuth, dir str

// JXAdapter creates an adapter to the jx code
func (o *EnvFactory) JXAdapter() *jxadapt.JXAdapter {
return jxadapt.NewJXAdapter(o.JXFactory, o.Gitter, o.BatchMode)
a := jxadapt.NewJXAdapter(o.JXFactory, o.Gitter, o.BatchMode)
a.NoOAuth = o.NoOAuth
return a
}
3 changes: 2 additions & 1 deletion pkg/jxadapt/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type JXAdapter struct {
JXFactory jxfactory.Factory
Gitter gits.Gitter
BatchMode bool
NoOAuth bool
gitConfig gitconfig.Context
}

Expand Down Expand Up @@ -65,7 +66,7 @@ func (a *JXAdapter) ScmClient(serverURL string, owner string, kind string) (*scm
token := ""
if kind == "" || kind == "github" {
kind = "github"
if !a.BatchMode {
if !a.BatchMode && !a.NoOAuth {
if a.gitConfig == nil {
a.gitConfig = gitconfig.New()
}
Expand Down
85 changes: 85 additions & 0 deletions pkg/reqhelpers/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package reqhelpers

import (
"fmt"
"strings"

"github.com/jenkins-x/jx/pkg/cloud"
"github.com/jenkins-x/jx/pkg/config"
"github.com/jenkins-x/jx/pkg/gits"
"github.com/spf13/cobra"
)

// AddRequirementsFlagsOptions add CLI options to the flags
func AddRequirementsFlagsOptions(cmd *cobra.Command, flags *RequirementBools) {
cmd.Flags().BoolVarP(&flags.AutoUpgrade, "autoupgrade", "", false, "enables or disables auto upgrades")
cmd.Flags().BoolVarP(&flags.EnvironmentRemote, "env-remote", "", false, "if enables then all other environments than dev (staging & production by default) will be configured to be in remote clusters")
cmd.Flags().BoolVarP(&flags.EnvironmentGitPublic, "env-git-public", "", false, "enables or disables whether the environment repositories should be public")
cmd.Flags().BoolVarP(&flags.GitPublic, "git-public", "", false, "enables or disables whether the project repositories should be public")
cmd.Flags().BoolVarP(&flags.GitOps, "gitops", "g", false, "enables or disables the use of gitops")
cmd.Flags().BoolVarP(&flags.Kaniko, "kaniko", "", false, "enables or disables the use of kaniko")
cmd.Flags().BoolVarP(&flags.Terraform, "terraform", "", false, "enables or disables the use of terraform")
cmd.Flags().BoolVarP(&flags.VaultRecreateBucket, "vault-recreate-bucket", "", false, "enables or disables whether to rereate the secret bucket on boot")
cmd.Flags().BoolVarP(&flags.VaultDisableURLDiscover, "vault-disable-url-discover", "", false, "override the default lookup of the Vault URL, could be incluster service or external ingress")
cmd.Flags().BoolVarP(&flags.ExternalDNS, "externaldns", "", false, "should we enable the ExternalDNS app to register DNS entries for Ingress resources")
cmd.Flags().BoolVarP(&flags.TLS, "tls", "", false, "enable TLS for Ingress")
cmd.Flags().StringVarP(&flags.Repository, "repository", "", "", "the artifact repository. Possible values are: "+strings.Join(config.RepositoryTypeValues, ", "))
}

// AddRequirementsOptions add CLI flags to the requirements
func AddRequirementsOptions(cmd *cobra.Command, r *config.RequirementsConfig) {
cmd.Flags().StringVarP(&r.BootConfigURL, "boot-config-url", "", "", "specify the boot configuration git URL")

// auto upgrade
cmd.Flags().StringVarP(&r.AutoUpdate.Schedule, "autoupdate-schedule", "", "", "the cron schedule for auto upgrading your cluster")

// cluster
cmd.Flags().StringVarP(&r.Cluster.ClusterName, "cluster", "c", "", "configures the cluster name")
cmd.Flags().StringVarP(&r.Cluster.Namespace, "namespace", "n", "", "configures the namespace to use")
cmd.Flags().StringVarP(&r.Cluster.Provider, "provider", "p", "", "configures the kubernetes provider. Supported providers: "+cloud.KubernetesProviderOptions())
cmd.Flags().StringVarP(&r.Cluster.ProjectID, "project", "", "", "configures the Google Project ID")
cmd.Flags().StringVarP(&r.Cluster.Registry, "registry", "", "", "configures the host name of the container registry")
cmd.Flags().StringVarP(&r.Cluster.Region, "region", "r", "", "configures the cloud region")
cmd.Flags().StringVarP(&r.Cluster.Zone, "zone", "z", "", "configures the cloud zone")

cmd.Flags().StringVarP(&r.Cluster.ExternalDNSSAName, "extdns-sa", "", "", "configures the External DNS service account name")
cmd.Flags().StringVarP(&r.Cluster.KanikoSAName, "kaniko-sa", "", "", "configures the Kaniko service account name")

AddGitRequirementsOptions(cmd, r)

// ingress
cmd.Flags().StringVarP(&r.Ingress.Domain, "domain", "d", "", "configures the domain name")
cmd.Flags().StringVarP(&r.Ingress.ServiceType, "service-type", "", "", "the Ingress controller Service Type such as NodePort if using on premise and you do not have a LoadBalancer service type support")
cmd.Flags().StringVarP(&r.Ingress.TLS.Email, "tls-email", "", "", "the TLS email address to enable TLS on the domain")
cmd.Flags().StringVarP(&r.Ingress.TLS.SecretName, "tls-secret", "", "", "the custom Kubernetes Secret name for the TLS certificate")

// storage
cmd.Flags().StringVarP(&r.Storage.Logs.URL, "bucket-logs", "", "", "the bucket URL to store logs")
cmd.Flags().StringVarP(&r.Storage.Backup.URL, "bucket-backups", "", "", "the bucket URL to store backups")
cmd.Flags().StringVarP(&r.Storage.Repository.URL, "bucket-repo", "", "", "the bucket URL to store repository artifacts")
cmd.Flags().StringVarP(&r.Storage.Reports.URL, "bucket-reports", "", "", "the bucket URL to store reports. If not specified default to te logs bucket")

// vault
cmd.Flags().StringVarP(&r.Vault.Name, "vault-name", "", "", "specify the vault name")
cmd.Flags().StringVarP(&r.Vault.Bucket, "vault-bucket", "", "", "specify the vault bucket")
cmd.Flags().StringVarP(&r.Vault.Keyring, "vault-keyring", "", "", "specify the vault key ring")
cmd.Flags().StringVarP(&r.Vault.Key, "vault-key", "", "", "specify the vault key")
cmd.Flags().StringVarP(&r.Vault.ServiceAccount, "vault-sa", "", "", "specify the vault Service Account name")

// velero
cmd.Flags().StringVarP(&r.Velero.ServiceAccount, "velero-sa", "", "", "specify the Velero Service Account name")
cmd.Flags().StringVarP(&r.Velero.Namespace, "velero-ns", "", "", "specify the Velero Namespace")

// version stream
cmd.Flags().StringVarP(&r.VersionStream.URL, "version-stream-url", "", "", "specify the Version Stream git URL")
cmd.Flags().StringVarP(&r.VersionStream.Ref, "version-stream-ref", "", "", "specify the Version Stream git reference (branch, tag, sha)")
}

// AddGitRequirementsOptions adds git specific overrides to the given requirements
func AddGitRequirementsOptions(cmd *cobra.Command, r *config.RequirementsConfig) {
cmd.Flags().StringVarP(&r.Cluster.GitKind, "git-kind", "", "", fmt.Sprintf("the kind of git repository to use. Possible values: %s", strings.Join(gits.KindGits, ", ")))
cmd.Flags().StringVarP(&r.Cluster.GitName, "git-name", "", "", "the name of the git repository")
cmd.Flags().StringVarP(&r.Cluster.GitServer, "git-server", "", "", "the git server host such as https://github.com or https://gitlab.com")
cmd.Flags().StringVarP(&r.Cluster.EnvironmentGitOwner, "env-git-owner", "", "", "the git owner (organisation or user) used to own the git repositories for the environments")
cmd.Flags().StringArrayVarP(&r.Cluster.DevEnvApprovers, "approver", "", nil, "the git user names of the approvers for the environments")
}
Loading

0 comments on commit dc76540

Please sign in to comment.