@@ -30,11 +30,16 @@ package commands
30
30
31
31
import (
32
32
"context"
33
+ "crypto/tls"
34
+ "crypto/x509"
33
35
_ "embed"
34
36
"fmt"
37
+ "net/http"
38
+ "net/url"
35
39
"os"
36
40
"regexp"
37
41
"strings"
42
+ "time"
38
43
39
44
"github.com/argoproj-labs/argocd-autopilot/pkg/git"
40
45
"github.com/codefresh-io/cli-v2/pkg/config"
@@ -90,6 +95,10 @@ func IsValidName(s string) (bool, error) {
90
95
return regexp .MatchString (`^[a-z]([-a-z0-9]{0,61}[a-z0-9])?$` , s )
91
96
}
92
97
98
+ func IsValidIngressHost (ingress string ) (bool , error ) {
99
+ return regexp .MatchString (`^(http|https)://` , ingress )
100
+ }
101
+
93
102
func askUserIfToInstallDemoResources (cmd * cobra.Command , sampleInstall * bool ) error {
94
103
if ! store .Get ().Silent && ! cmd .Flags ().Changed ("sample-install" ) {
95
104
templates := & promptui.SelectTemplates {
@@ -360,3 +369,94 @@ func getIngressHostFromUserInput(cmd *cobra.Command, ingressHost *string) error
360
369
361
370
return nil
362
371
}
372
+
373
+ func checkIngressHostCertificate (ctx context.Context , ingress string ) (bool , error ) {
374
+ var err error
375
+ match , _ := regexp .MatchString (`^http://` , ingress )
376
+ if match { //if user provided http ingress
377
+ log .G (ctx ).Warn ("The ingress host uses an insecure protocol. The browser may block subsequent runtime requests from the UI unless explicitly approved." )
378
+
379
+ return true , nil
380
+ }
381
+
382
+ res , err := http .Get (ingress )
383
+
384
+ if err == nil {
385
+ res .Body .Close ()
386
+ return true , nil
387
+ }
388
+
389
+ urlErr , ok := err .(* url.Error )
390
+ if ! ok {
391
+ return false , err
392
+ }
393
+ _ , ok1 := urlErr .Err .(x509.CertificateInvalidError )
394
+ _ , ok2 := urlErr .Err .(x509.SystemRootsError )
395
+ _ , ok3 := urlErr .Err .(x509.UnknownAuthorityError )
396
+ _ , ok4 := urlErr .Err .(x509.ConstraintViolationError )
397
+ _ , ok5 := urlErr .Err .(x509.HostnameError )
398
+
399
+ certErr := ok1 || ok2 || ok3 || ok4 || ok5
400
+ if ! certErr {
401
+ return false , fmt .Errorf ("failed with non-certificate error: %w" , err )
402
+ }
403
+
404
+ insecureOk := checkIngressHostWithInsecure (ingress )
405
+ if ! insecureOk {
406
+ return false , fmt .Errorf ("insecure call failed: %w" , err )
407
+ }
408
+
409
+ return false , nil
410
+ }
411
+
412
+ func checkIngressHostWithInsecure (ingress string ) bool {
413
+ httpClient := & http.Client {}
414
+ httpClient .Timeout = 10 * time .Second
415
+ customTransport := http .DefaultTransport .(* http.Transport ).Clone ()
416
+ customTransport .TLSClientConfig = & tls.Config {InsecureSkipVerify : true }
417
+ httpClient .Transport = customTransport
418
+ req , err := http .NewRequest ("GET" , ingress , nil )
419
+ if err != nil {
420
+ return false
421
+ }
422
+ res , err := httpClient .Do (req )
423
+ if err != nil {
424
+ return false
425
+ }
426
+ res .Body .Close ()
427
+ return true
428
+ }
429
+
430
+ func askUserIfToProceedWithInsecure (ctx context.Context ) error {
431
+ if store .Get ().InsecureIngressHost {
432
+ return nil
433
+ }
434
+ if store .Get ().Silent {
435
+ return fmt .Errorf ("cancelled installation due to invalid ingress host certificate" )
436
+ }
437
+
438
+ templates := & promptui.SelectTemplates {
439
+ Selected : "{{ . | yellow }} " ,
440
+ }
441
+
442
+ log .G (ctx ).Warnf ("The provided ingressHost does not have a valid certificate." )
443
+ labelStr := fmt .Sprintf ("%vDo you wish to continue the installation with insecure ingress host mode?%v" , CYAN , COLOR_RESET )
444
+
445
+ prompt := promptui.Select {
446
+ Label : labelStr ,
447
+ Items : []string {"Yes" , "Cancel installation" },
448
+ Templates : templates ,
449
+ }
450
+
451
+ _ , result , err := prompt .Run ()
452
+ if err != nil {
453
+ return fmt .Errorf ("Prompt error: %w" , err )
454
+ }
455
+
456
+ if result == "Yes" {
457
+ store .Get ().InsecureIngressHost = true
458
+ } else {
459
+ return fmt .Errorf ("cancelled installation due to invalid ingress host certificate" )
460
+ }
461
+ return nil
462
+ }
0 commit comments