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

     1  package post
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/olli-ai/jx/v2/pkg/errorutil"
     7  
     8  	"github.com/olli-ai/jx/v2/pkg/cmd/opts/step"
     9  
    10  	"github.com/olli-ai/jx/v2/pkg/cmd/helper"
    11  
    12  	v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1"
    13  	"github.com/olli-ai/jx/v2/pkg/gits"
    14  	"github.com/olli-ai/jx/v2/pkg/jenkinsfile"
    15  
    16  	"github.com/jenkins-x/jx-logging/pkg/log"
    17  	"github.com/olli-ai/jx/v2/pkg/kube"
    18  	"github.com/olli-ai/jx/v2/pkg/util"
    19  
    20  	"github.com/pkg/errors"
    21  
    22  	"github.com/olli-ai/jx/v2/pkg/cmd/opts"
    23  	"github.com/olli-ai/jx/v2/pkg/cmd/templates"
    24  
    25  	"github.com/spf13/cobra"
    26  )
    27  
    28  // StepPostInstallOptions contains the command line flags
    29  type StepPostInstallOptions struct {
    30  	step.StepOptions
    31  
    32  	EnvJobCredentials string
    33  
    34  	Results StepPostInstallResults
    35  }
    36  
    37  // StepPostInstallResults contains the command outputs mostly for testing purposes
    38  type StepPostInstallResults struct {
    39  	GitProviders map[string]gits.GitProvider
    40  }
    41  
    42  var (
    43  	stepPostInstallLong = templates.LongDesc(`
    44  		This pipeline step ensures that all the necessary jobs are imported and the webhooks set up - e.g. for the current Environments.
    45  
    46  		It is designed to work with GitOps based development environments where the permanent Environments like Staging and Production are defined in a git repository.
    47  		This step is used to ensure that all the 'Environment' resources have their associated CI+CD jobs setup in Jenkins or Prow with the necessary webhooks in place.
    48  `)
    49  
    50  	stepPostInstallExample = templates.Examples(`
    51  		jx step post install
    52  `)
    53  )
    54  
    55  // NewCmdStepPostInstall creates the command object
    56  func NewCmdStepPostInstall(commonOpts *opts.CommonOptions) *cobra.Command {
    57  	options := &StepPostInstallOptions{
    58  		StepOptions: step.StepOptions{
    59  			CommonOptions: commonOpts,
    60  		},
    61  	}
    62  
    63  	cmd := &cobra.Command{
    64  		Use:     "install",
    65  		Short:   "Runs any post install actions",
    66  		Long:    stepPostInstallLong,
    67  		Example: stepPostInstallExample,
    68  		Run: func(cmd *cobra.Command, args []string) {
    69  			options.Cmd = cmd
    70  			options.Args = args
    71  			err := options.Run()
    72  			helper.CheckErr(err)
    73  		},
    74  	}
    75  
    76  	cmd.Flags().StringVarP(&options.EnvJobCredentials, "env-job-credentials", "", "", "The Jenkins credentials used by the GitOps Job for this environment")
    77  	return cmd
    78  }
    79  
    80  // Run implements this command
    81  func (o *StepPostInstallOptions) Run() (err error) {
    82  	apisClient, err := o.ApiExtensionsClient()
    83  	if err != nil {
    84  		return errors.Wrap(err, "failed to create the API extensions client")
    85  	}
    86  	err = kube.RegisterAllCRDs(apisClient)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	jxClient, ns, err := o.JXClientAndDevNamespace()
    91  	if err != nil {
    92  		return errors.Wrap(err, "cannot create the JX client")
    93  	}
    94  
    95  	envMap, names, err := kube.GetEnvironments(jxClient, ns)
    96  	if err != nil {
    97  		return errors.Wrapf(err, "cannot load Environments in namespace %s", ns)
    98  	}
    99  
   100  	teamSettings, err := o.TeamSettings()
   101  	if err != nil {
   102  		return errors.Wrapf(err, "cannot load the TeamSettings from dev namespace %s", ns)
   103  	}
   104  	branchPattern := teamSettings.BranchPatterns
   105  
   106  	envDir, err := util.EnvironmentsDir()
   107  	if err != nil {
   108  		return errors.Wrapf(err, "cannot find the environments git clone local directory")
   109  	}
   110  	authConfigSvc, err := o.GitAuthConfigService()
   111  	if err != nil {
   112  		return errors.Wrapf(err, "cannot create the git auth config service")
   113  	}
   114  
   115  	prow, err := o.IsProw()
   116  	if err != nil {
   117  		return errors.Wrapf(err, "cannot determine if the current team is using Prow")
   118  	}
   119  
   120  	errs := []error{}
   121  	for _, name := range names {
   122  		env := envMap[name]
   123  		if env == nil || (env.Spec.Kind != v1.EnvironmentKindTypePermanent && env.Spec.Kind != v1.EnvironmentKindTypeDevelopment) {
   124  			continue
   125  		}
   126  		//gitRef := env.Spec.Source.GitRef
   127  		gitURL := env.Spec.Source.URL
   128  		if gitURL == "" {
   129  			continue
   130  		}
   131  		gitInfo, err := gits.ParseGitURL(gitURL)
   132  		if err != nil {
   133  			log.Logger().Errorf("failed to parse git URL %s for Environment %s due to: %s", gitURL, name, err)
   134  			errs = append(errs, errors.Wrapf(err, "failed to parse git URL %s for Environment %s", gitURL, name))
   135  			continue
   136  		}
   137  
   138  		gitProvider, err := o.GitProviderForURL(gitURL, fmt.Sprintf("Environment %s", name))
   139  		if err != nil {
   140  			log.Logger().Errorf("failed to create git provider for Environment %s with git URL %s due to: %s", name, gitURL, err)
   141  			errs = append(errs, errors.Wrapf(err, "failed to create git provider for Environment %s with git URL %s", name, gitURL))
   142  			continue
   143  		}
   144  		if o.Results.GitProviders == nil {
   145  			o.Results.GitProviders = map[string]gits.GitProvider{}
   146  		}
   147  		o.Results.GitProviders[name] = gitProvider
   148  
   149  		if prow {
   150  			config := authConfigSvc.Config()
   151  			u := gitInfo.HostURL()
   152  			server := config.GetOrCreateServer(u)
   153  			if len(server.Users) == 0 {
   154  				// lets check if the host was used in `~/.jx/gitAuth.yaml` instead of URL
   155  				s2 := config.GetOrCreateServer(gitInfo.Host)
   156  				if s2 != nil && len(s2.Users) > 0 {
   157  					server = s2
   158  					u = gitInfo.Host
   159  				}
   160  			}
   161  			user, err := o.PickPipelineUserAuth(config, server)
   162  			if err != nil {
   163  				return err
   164  			}
   165  			if user.Username == "" {
   166  				return fmt.Errorf("could not find a username for git server %s", u)
   167  			}
   168  			err = authConfigSvc.SaveConfig()
   169  			if err != nil {
   170  				return err
   171  			}
   172  			// register the webhook
   173  			return o.CreateWebhookProw(gitURL, gitProvider)
   174  		}
   175  
   176  		err = o.ImportProject(gitURL, envDir, jenkinsfile.Name, branchPattern, o.EnvJobCredentials, false, gitProvider, authConfigSvc, true, o.BatchMode)
   177  		if err != nil {
   178  			log.Logger().Errorf("failed to import Environment %s with git URL %s due to: %s", name, gitURL, err)
   179  			errs = append(errs, errors.Wrapf(err, "failed to import Environment %s with git URL %s", name, gitURL))
   180  		}
   181  	}
   182  	return errorutil.CombineErrors(errs...)
   183  }