github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/step/verify/step_verify_dns.go (about)

     1  package verify
     2  
     3  import (
     4  	"net"
     5  	"time"
     6  
     7  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     8  
     9  	"github.com/cenkalti/backoff"
    10  	"github.com/jenkins-x/jx-logging/pkg/log"
    11  	"github.com/olli-ai/jx/v2/pkg/cmd/helper"
    12  	"github.com/olli-ai/jx/v2/pkg/cmd/opts"
    13  	"github.com/olli-ai/jx/v2/pkg/cmd/opts/step"
    14  	"github.com/olli-ai/jx/v2/pkg/cmd/templates"
    15  	"github.com/pkg/errors"
    16  	"github.com/spf13/cobra"
    17  )
    18  
    19  var (
    20  	stepVerifyDNSLong = templates.LongDesc(`
    21  		This step checks that dns has propagated for all ingresses
    22  	`)
    23  
    24  	stepVerifyDNSExample = templates.Examples(`
    25          jx step verify dns --timeout 10m
    26  	`)
    27  )
    28  
    29  // StepVerifyDNSOptions options for step verify dns command
    30  type StepVerifyDNSOptions struct {
    31  	step.StepOptions
    32  
    33  	Timeout time.Duration
    34  }
    35  
    36  // NewCmdStepVerifyDNS creates a new verify url command
    37  func NewCmdStepVerifyDNS(commonOpts *opts.CommonOptions) *cobra.Command {
    38  	options := StepVerifyDNSOptions{
    39  		StepOptions: step.StepOptions{
    40  			CommonOptions: commonOpts,
    41  		},
    42  	}
    43  
    44  	cmd := &cobra.Command{
    45  		Use:     "dns",
    46  		Short:   "Verifies DNS resolution for ingress rules",
    47  		Long:    stepVerifyDNSLong,
    48  		Example: stepVerifyDNSExample,
    49  		Run: func(cmd *cobra.Command, args []string) {
    50  			options.Cmd = cmd
    51  			options.Args = args
    52  			err := options.Run()
    53  			helper.CheckErr(err)
    54  		},
    55  	}
    56  
    57  	cmd.Flags().DurationVarP(&options.Timeout, optionTimeout, "t", 10*time.Minute, "The default timeout for the endpoint to return the expected HTTP code")
    58  	return cmd
    59  }
    60  
    61  func (o *StepVerifyDNSOptions) checkFlags() error {
    62  	return nil
    63  }
    64  
    65  // Run waits with exponential backoff for an endpoint to return an expected HTTP status code
    66  func (o *StepVerifyDNSOptions) Run() error {
    67  	if err := o.checkFlags(); err != nil {
    68  		return errors.Wrap(err, "checking flags")
    69  	}
    70  
    71  	client, ns, err := o.KubeClientAndDevNamespace()
    72  	if err != nil {
    73  		return errors.Wrap(err, "unable to get kubeclient")
    74  	}
    75  
    76  	ingresses, err := client.ExtensionsV1beta1().Ingresses(ns).List(v1.ListOptions{})
    77  	if err != nil {
    78  		return errors.Wrap(err, "unable to get ingresses")
    79  	}
    80  
    81  	for _, i := range ingresses.Items {
    82  		for _, h := range i.Spec.Rules {
    83  			log.Logger().Infof("Checking DNS resolution for %s", h.Host)
    84  
    85  			err := retry(o.Timeout, func() error {
    86  				_, err := net.LookupIP(h.Host)
    87  				if err != nil {
    88  					return errors.Wrapf(err, "Could not resolve: %v", h.Host)
    89  				}
    90  
    91  				return nil
    92  			}, func(e error, d time.Duration) {
    93  				log.Logger().Infof("resolution failed, backing of for %s", d)
    94  			})
    95  			if err != nil {
    96  				return errors.Wrap(err, "unable to resolve DNS")
    97  			}
    98  			log.Logger().Infof("%s resolved", h.Host)
    99  		}
   100  	}
   101  
   102  	return nil
   103  }
   104  
   105  // retry retries with exponential backoff the given function
   106  func retry(maxElapsedTime time.Duration, f func() error, n func(error, time.Duration)) error {
   107  	bo := backoff.NewExponentialBackOff()
   108  	bo.MaxElapsedTime = maxElapsedTime
   109  	bo.InitialInterval = 2 * time.Second
   110  	bo.Reset()
   111  	return backoff.RetryNotify(f, bo, n)
   112  
   113  }