Skip to content

Commit 567571e

Browse files
CR-8893 get ingress class from user (#218)
* wip- added ensureIngressClass, getIngressClassFromUserSelect * added --ingress-class to installation and create git source * wip * small change * added ingressClass to the finalParameters * filter classes by name label * add check to ingress class provided by flag * bypass-ingress-class-check hidden flag (#222) * added bypass-ingress-class-check hidden flag * bump * lint fix * implement bypass-ingress-class-checks flag * removes duplicate flag * removed duplicate flag * added docs link * bump * added link to upgrade error * docs * improve after review * print for debug * improve strings * bump * added err report * indent * bump
1 parent d027426 commit 567571e

File tree

11 files changed

+157
-40
lines changed

11 files changed

+157
-40
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION=v0.0.208
1+
VERSION=v0.0.209
22

33
OUT_DIR=dist
44
YEAR?=$(shell date +"%Y")

cmd/commands/common.go

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,21 +113,32 @@ func askUserIfToInstallDemoResources(cmd *cobra.Command, sampleInstall *bool) er
113113

114114
func ensureRepo(cmd *cobra.Command, runtimeName string, cloneOpts *git.CloneOptions, fromAPI bool) error {
115115
ctx := cmd.Context()
116-
if cloneOpts.Repo == "" {
117-
if fromAPI {
118-
runtimeData, err := cfConfig.NewClient().V2().Runtime().Get(ctx, runtimeName)
119-
if err != nil {
120-
return fmt.Errorf("failed getting runtime repo information: %w", err)
121-
}
122-
if runtimeData.Repo != nil {
123-
die(cmd.Flags().Set("repo", *runtimeData.Repo))
124-
return nil
125-
}
116+
if cloneOpts.Repo != "" {
117+
return nil
118+
}
119+
120+
if fromAPI {
121+
runtimeData, err := cfConfig.NewClient().V2().Runtime().Get(ctx, runtimeName)
122+
if err != nil {
123+
return fmt.Errorf("failed getting runtime repo information: %w", err)
126124
}
127-
if !store.Get().Silent {
128-
return getRepoFromUserInput(cmd)
125+
if runtimeData.Repo != nil {
126+
die(cmd.Flags().Set("repo", *runtimeData.Repo))
127+
return nil
128+
}
129+
}
130+
131+
if !store.Get().Silent {
132+
err := getRepoFromUserInput(cmd)
133+
if err != nil {
134+
return err
129135
}
130136
}
137+
138+
if cloneOpts.Repo == "" {
139+
return fmt.Errorf("must enter a valid installation repository URL")
140+
}
141+
131142
return nil
132143
}
133144

@@ -211,6 +222,29 @@ func getRuntimeNameFromUserSelect(ctx context.Context, runtimeName *string) erro
211222
return nil
212223
}
213224

225+
func getIngressClassFromUserSelect(ctx context.Context, ingressClassNames []string, ingressClass *string) error {
226+
templates := &promptui.SelectTemplates{
227+
Selected: "{{ . | yellow }} ",
228+
}
229+
230+
labelStr := fmt.Sprintf("%vSelect ingressClass%v", CYAN, COLOR_RESET)
231+
232+
prompt := promptui.Select{
233+
Label: labelStr,
234+
Items: ingressClassNames,
235+
Templates: templates,
236+
}
237+
238+
_, result, err := prompt.Run()
239+
if err != nil {
240+
return fmt.Errorf("Prompt error: %w", err)
241+
}
242+
243+
*ingressClass = result
244+
245+
return nil
246+
}
247+
214248
func ensureGitToken(cmd *cobra.Command, cloneOpts *git.CloneOptions) error {
215249
if cloneOpts.Auth.Password == "" && !store.Get().Silent {
216250
return getGitTokenFromUserInput(cmd)

cmd/commands/git-source.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type (
5959
Exclude string
6060
Include string
6161
IngressHost string
62+
IngressClass string
6263
}
6364

6465
GitSourceDeleteOptions struct {
@@ -82,10 +83,11 @@ type (
8283
}
8384

8485
gitSourceGithubExampleOptions struct {
85-
runtimeName string
86-
gsCloneOpts *git.CloneOptions
87-
gsFs fs.FS
88-
ingressHost string
86+
runtimeName string
87+
gsCloneOpts *git.CloneOptions
88+
gsFs fs.FS
89+
ingressHost string
90+
ingressClass string
8991
}
9092
)
9193

@@ -114,6 +116,7 @@ func NewGitSourceCreateCommand() *cobra.Command {
114116
insCloneOpts *git.CloneOptions
115117
gsCloneOpts *git.CloneOptions
116118
createRepo bool
119+
ingressClass string
117120
)
118121

119122
cmd := &cobra.Command{
@@ -138,6 +141,10 @@ func NewGitSourceCreateCommand() *cobra.Command {
138141
log.G(ctx).Fatal("must enter a valid value to --git-src-repo. Example: https://github.com/owner/repo-name/path/to/workflow")
139142
}
140143

144+
if ingressClass == "" && !store.Get().BypassIngressClassCheck {
145+
log.G(ctx).Fatal("must enter a valid ingressClass name to --ingress-class")
146+
}
147+
141148
err := ensureRepo(cmd, args[0], insCloneOpts, true)
142149
if err != nil {
143150
return err
@@ -174,11 +181,13 @@ func NewGitSourceCreateCommand() *cobra.Command {
174181
GsName: args[1],
175182
RuntimeName: args[0],
176183
CreateDemoResources: false,
184+
IngressClass: ingressClass,
177185
})
178186
},
179187
}
180188

181189
cmd.Flags().BoolVar(&createRepo, "create-repo", false, "If true, will create the specified git-source repo in case it doesn't already exist")
190+
cmd.Flags().StringVar(&ingressClass, "ingress-class", "", "The ingress class name")
182191
cmd.Flags().BoolVar(&store.Get().BypassIngressClassCheck, "bypass-ingress-class-check", false, "Disables the ingress class check during git-source installation")
183192
util.Die(cmd.Flags().MarkHidden("bypass-ingress-class-check"))
184193

@@ -236,10 +245,11 @@ func createDemoResources(ctx context.Context, opts *GitSourceCreateOptions, gsRe
236245
}
237246

238247
err = createGithubExamplePipeline(&gitSourceGithubExampleOptions{
239-
runtimeName: opts.RuntimeName,
240-
gsCloneOpts: opts.GsCloneOpts,
241-
gsFs: gsFs,
242-
ingressHost: opts.IngressHost,
248+
runtimeName: opts.RuntimeName,
249+
gsCloneOpts: opts.GsCloneOpts,
250+
gsFs: gsFs,
251+
ingressHost: opts.IngressHost,
252+
ingressClass: opts.IngressClass,
243253
})
244254
if err != nil {
245255
return fmt.Errorf("failed to create github example pipeline. Error: %w", err)
@@ -650,7 +660,7 @@ func createDemoWorkflowTemplate(gsFs fs.FS, runtimeName string) error {
650660

651661
func createGithubExamplePipeline(opts *gitSourceGithubExampleOptions) error {
652662
// Create an ingress that will manage external access to the github eventsource service
653-
ingress := createGithubExampleIngress()
663+
ingress := createGithubExampleIngress(opts.ingressClass)
654664
ingressFilePath := opts.gsFs.Join(opts.gsCloneOpts.Path(), store.Get().GithubExampleIngressFileName)
655665
err := opts.gsCloneOpts.FS.WriteYamls(ingressFilePath, ingress)
656666
if err != nil {
@@ -677,9 +687,10 @@ func createGithubExamplePipeline(opts *gitSourceGithubExampleOptions) error {
677687
return nil
678688
}
679689

680-
func createGithubExampleIngress() *netv1.Ingress {
690+
func createGithubExampleIngress(ingressClass string) *netv1.Ingress {
681691
return ingressutil.CreateIngress(&ingressutil.CreateIngressOptions{
682-
Name: store.Get().CodefreshDeliveryPipelines,
692+
Name: store.Get().CodefreshDeliveryPipelines,
693+
IngressClassName: ingressClass,
683694
Paths: []ingressutil.IngressPath{
684695
{
685696
Path: store.Get().GithubExampleEventSourceEndpointPath,

cmd/commands/runtime.go

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ type (
7373
RuntimeToken string
7474
RuntimeStoreIV string
7575
IngressHost string
76+
IngressClass string
7677
Insecure bool
7778
InstallDemoResources bool
7879
Version *semver.Version
@@ -189,6 +190,7 @@ func NewRuntimeInstallCommand() *cobra.Command {
189190
"Runtime name": installationOpts.RuntimeName,
190191
"Repository URL": installationOpts.InsCloneOpts.Repo,
191192
"Ingress host": installationOpts.IngressHost,
193+
"IngressClass": installationOpts.IngressClass,
192194
"Installing demo resources": strconv.FormatBool(installationOpts.InstallDemoResources),
193195
}
194196

@@ -206,6 +208,7 @@ func NewRuntimeInstallCommand() *cobra.Command {
206208
}
207209

208210
cmd.Flags().StringVar(&installationOpts.IngressHost, "ingress-host", "", "The ingress host")
211+
cmd.Flags().StringVar(&installationOpts.IngressClass, "ingress-class", "", "The ingress class name")
209212
cmd.Flags().StringVar(&installationOpts.versionStr, "version", "", "The runtime version to install (default: latest)")
210213
cmd.Flags().BoolVar(&installationOpts.InstallDemoResources, "demo-resources", true, "Installs demo resources (default: true)")
211214
cmd.Flags().DurationVar(&store.Get().WaitTimeout, "wait-timeout", store.Get().WaitTimeout, "How long to wait for the runtime components to be ready")
@@ -273,6 +276,12 @@ func runtimeInstallCommandPreRunHandler(cmd *cobra.Command, opts *RuntimeInstall
273276
return fmt.Errorf("%w", err)
274277
}
275278

279+
err = ensureIngressClass(cmd.Context(), opts)
280+
handleCliStep(reporter.InstallStepPreCheckEnsureIngressClass, "Getting ingress class", err, false)
281+
if err != nil {
282+
return err
283+
}
284+
276285
err = ensureRepo(cmd, opts.RuntimeName, opts.InsCloneOpts, false)
277286
handleCliStep(reporter.InstallStepPreCheckEnsureRuntimeRepo, "Getting runtime repo", err, false)
278287
if err != nil {
@@ -397,6 +406,54 @@ func ensureIngressHost(cmd *cobra.Command, opts *RuntimeInstallOptions) error {
397406
return nil
398407
}
399408

409+
func ensureIngressClass(ctx context.Context, opts *RuntimeInstallOptions) error {
410+
if store.Get().BypassIngressClassCheck {
411+
return nil
412+
}
413+
414+
fmt.Print("Retrieving ingress class info from your cluster...\n")
415+
416+
cs := opts.KubeFactory.KubernetesClientSetOrDie()
417+
ingressClassList, err := cs.NetworkingV1().IngressClasses().List(ctx, metav1.ListOptions{})
418+
if err != nil {
419+
return fmt.Errorf("failed to get ingressClass list from your cluster: %w", err)
420+
}
421+
422+
var ingressClassNames []string
423+
var isValidClass bool
424+
for _, ic := range ingressClassList.Items {
425+
if ic.ObjectMeta.Labels["app.kubernetes.io/name"] == "ingress-nginx" {
426+
ingressClassNames = append(ingressClassNames, ic.Name)
427+
if opts.IngressClass == ic.Name {
428+
isValidClass = true
429+
}
430+
}
431+
}
432+
433+
if opts.IngressClass != "" { //if user provided ingress class by flag
434+
if isValidClass {
435+
return nil
436+
}
437+
return fmt.Errorf("Ingress Class '%s' is not supported. Only the ingress class of type NGINX is supported. for more information: %s", opts.IngressClass, store.Get().RequirementsLink)
438+
}
439+
440+
if len(ingressClassNames) == 0 {
441+
return fmt.Errorf("No ingressClasses of type nginx were found. please install a nginx ingress controller on your cluster before installing a runtime. see instructions at: %s", store.Get().RequirementsLink)
442+
}
443+
444+
if len(ingressClassNames) == 1 {
445+
log.G(ctx).Info("Using ingress class: ", ingressClassNames[0])
446+
opts.IngressClass = ingressClassNames[0]
447+
return nil
448+
}
449+
450+
if !store.Get().Silent {
451+
return getIngressClassFromUserSelect(ctx, ingressClassNames, &opts.IngressClass)
452+
}
453+
454+
return fmt.Errorf("Please add the --ingress-class flag and define its value")
455+
}
456+
400457
func getComponents(rt *runtime.Runtime, opts *RuntimeInstallOptions) []string {
401458
var componentNames []string
402459
for _, component := range rt.Spec.Components {
@@ -547,6 +604,7 @@ func RunRuntimeInstall(ctx context.Context, opts *RuntimeInstallOptions) error {
547604
RuntimeName: opts.RuntimeName,
548605
CreateDemoResources: opts.InstallDemoResources,
549606
IngressHost: opts.IngressHost,
607+
IngressClass: opts.IngressClass,
550608
})
551609
handleCliStep(reporter.InstallStepCreateGitsource, gitSrcMessage, err, true)
552610
if err != nil {
@@ -611,7 +669,7 @@ func addDefaultGitIntegration(ctx context.Context, runtime string, opts *apmodel
611669
func installComponents(ctx context.Context, opts *RuntimeInstallOptions, rt *runtime.Runtime) error {
612670
var err error
613671
if opts.IngressHost != "" {
614-
if err = createWorkflowsIngress(ctx, opts.InsCloneOpts, rt); err != nil {
672+
if err = createWorkflowsIngress(ctx, opts, rt); err != nil {
615673
return fmt.Errorf("failed to patch Argo-Workflows ingress: %w", err)
616674
}
617675
}
@@ -674,7 +732,7 @@ func preInstallationChecks(ctx context.Context, opts *RuntimeInstallOptions) err
674732
}
675733

676734
if rt.Spec.DefVersion.GreaterThan(store.Get().MaxDefVersion) {
677-
err = fmt.Errorf("your cli version is out of date. please upgrade to the latest version before installing")
735+
err = fmt.Errorf("your cli version is out of date. please upgrade to the latest version before installing. for more information: %s", store.Get().DownloadCliLink)
678736
}
679737
handleCliStep(reporter.InstallStepRunPreCheckEnsureCliVersion, "Checking CLI version", err, false)
680738
if err != nil {
@@ -1160,16 +1218,17 @@ func persistRuntime(ctx context.Context, cloneOpts *git.CloneOptions, rt *runtim
11601218
return apu.PushWithMessage(ctx, r, "Persisted runtime data")
11611219
}
11621220

1163-
func createWorkflowsIngress(ctx context.Context, cloneOpts *git.CloneOptions, rt *runtime.Runtime) error {
1164-
r, fs, err := cloneOpts.GetRepo(ctx)
1221+
func createWorkflowsIngress(ctx context.Context, opts *RuntimeInstallOptions, rt *runtime.Runtime) error {
1222+
r, fs, err := opts.InsCloneOpts.GetRepo(ctx)
11651223
if err != nil {
11661224
return err
11671225
}
11681226

11691227
overlaysDir := fs.Join(apstore.Default.AppsDir, store.Get().WorkflowsIngressPath, apstore.Default.OverlaysDir, rt.Name)
11701228
ingress := ingressutil.CreateIngress(&ingressutil.CreateIngressOptions{
1171-
Name: rt.Name + store.Get().WorkflowsIngressName,
1172-
Namespace: rt.Namespace,
1229+
Name: rt.Name + store.Get().WorkflowsIngressName,
1230+
Namespace: rt.Namespace,
1231+
IngressClassName: opts.IngressClass,
11731232
Annotations: map[string]string{
11741233
"ingress.kubernetes.io/protocol": "https",
11751234
"ingress.kubernetes.io/rewrite-target": "/$2",
@@ -1254,8 +1313,9 @@ func configureAppProxy(ctx context.Context, opts *RuntimeInstallOptions, rt *run
12541313

12551314
if opts.IngressHost != "" {
12561315
ingress := ingressutil.CreateIngress(&ingressutil.CreateIngressOptions{
1257-
Name: rt.Name + store.Get().AppProxyIngressName,
1258-
Namespace: rt.Namespace,
1316+
Name: rt.Name + store.Get().AppProxyIngressName,
1317+
Namespace: rt.Namespace,
1318+
IngressClassName: opts.IngressClass,
12591319
Paths: []ingressutil.IngressPath{
12601320
{
12611321
Path: fmt.Sprintf("/%s", store.Get().AppProxyIngressPath),

docs/commands/cli-v2_git-source_create.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ cli-v2 git-source create runtime_name git-source_name [flags]
2424
-t, --git-token string Your git provider api token [GIT_TOKEN]
2525
-u, --git-user string Your git provider user name [GIT_USER] (not required in GitHub)
2626
-h, --help help for create
27+
--ingress-class string The ingress class name
2728
--repo string Repository URL [GIT_REPO]
2829
```
2930

docs/commands/cli-v2_runtime_install.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ cli-v2 runtime install [runtime_name] [flags]
3737
-t, --git-token string Your git provider api token [GIT_TOKEN]
3838
-u, --git-user string Your git provider user name [GIT_USER] (not required in GitHub)
3939
-h, --help help for install
40+
--ingress-class string The ingress class name
4041
--ingress-host string The ingress host
4142
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
4243
-n, --namespace string If present, the namespace scope for this CLI request

docs/releases/release_notes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cf version
2323

2424
```bash
2525
# download and extract the binary
26-
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.208/cf-linux-amd64.tar.gz | tar zx
26+
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.209/cf-linux-amd64.tar.gz | tar zx
2727

2828
# move the binary to your $PATH
2929
mv ./cf-linux-amd64 /usr/local/bin/cf
@@ -36,7 +36,7 @@ cf version
3636

3737
```bash
3838
# download and extract the binary
39-
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.208/cf-darwin-amd64.tar.gz | tar zx
39+
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.209/cf-darwin-amd64.tar.gz | tar zx
4040

4141
# move the binary to your $PATH
4242
mv ./cf-darwin-amd64 /usr/local/bin/cf

manifests/runtime.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
namespace: '{{ namespace }}'
66
spec:
77
defVersion: 1.0.0
8-
version: 0.0.208
8+
version: 0.0.209
99
bootstrapSpecifier: github.com/codefresh-io/cli-v2/manifests/argo-cd
1010
components:
1111
- name: events

pkg/reporter/reporter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const (
6363
InstallStepPreCheckGetRuntimeName CliStep = "install.pre-check.step.get-runtime-name"
6464
InstallStepPreCheckRuntimeNameValidation CliStep = "install.pre-check.step.runtime-name-validation"
6565
InstallStepPreCheckGetKubeContext CliStep = "install.pre-check.step.get-kube-context"
66+
InstallStepPreCheckEnsureIngressClass CliStep = "install.pre-check.step.ensure-ingress-class"
6667
InstallStepPreCheckEnsureRuntimeRepo CliStep = "install.pre-check.step.ensure-runtime-repo"
6768
InstallStepPreCheckEnsureGitToken CliStep = "install.pre-check.step.ensure-git-token"
6869
InstallStepPreCheckEnsureIngressHost CliStep = "install.pre-check.step.ensure-ingress-host"

pkg/store/store.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ type Store struct {
124124
ReplicaSetReporterServiceAccount string
125125
ReplicaSetResourceName string
126126
WorkflowResourceName string
127+
RequirementsLink string
128+
DownloadCliLink string
127129
RolloutReporterName string
128130
RolloutResourceName string
129131
RolloutReporterServiceAccount string
@@ -213,6 +215,8 @@ func init() {
213215
s.RolloutResourceName = "rollouts"
214216
s.RolloutReporterServiceAccount = "rollout-reporter-sa"
215217
s.SegmentWriteKey = segmentWriteKey
218+
s.RequirementsLink = "https://codefresh.io/csdp-docs/docs/runtime/requirements/"
219+
s.DownloadCliLink = "https://codefresh.io/csdp-docs/docs/clients/csdp-cli/"
216220
initVersion()
217221
}
218222

0 commit comments

Comments
 (0)