github.com/jenkins-x/jx/v2@v2.1.155/pkg/github/github_app.go (about) 1 package github 2 3 import ( 4 "fmt" 5 6 "encoding/json" 7 8 "github.com/jenkins-x/jx-logging/pkg/log" 9 "github.com/jenkins-x/jx/v2/pkg/cmd/clients" 10 "github.com/jenkins-x/jx/v2/pkg/config" 11 "github.com/jenkins-x/jx/v2/pkg/kube" 12 "github.com/jenkins-x/jx/v2/pkg/util" 13 "github.com/pkg/errors" 14 ) 15 16 //GithubApp represents a Github App install 17 type GithubApp struct { 18 Factory clients.Factory 19 } 20 21 type response struct { 22 Installed bool 23 AccessToRepo bool 24 URL string 25 AppName string 26 } 27 28 // Install - confirms that the github app is installed and if it isn't then prints out a url for the user to install 29 func (gh *GithubApp) Install(owner string, repo string, fileHandles util.IOFileHandles, newRepo bool) (bool, error) { 30 installed, accessToRepo, url, appName, err := gh.isInstalled(owner, repo) 31 if err != nil { 32 return false, errors.Wrap(err, "when querying whether the Github App is installed") 33 } 34 if appName == "" { 35 // if the appName is empty lets use Jenkins X as the default 36 appName = "Jenkins X" 37 } 38 39 if installed { 40 fmt.Println(fmt.Sprintf("'%s' Github App installed", util.ColorInfo(appName))) 41 if newRepo { 42 // if this is a new repo we can't confirm if it has access at this stage 43 return false, nil 44 } 45 if !accessToRepo { 46 fmt.Fprintf(fileHandles.Out, "Please confirm '%s' Github App has access to repository %s. Click this url \n%s\n\n", util.ColorInfo(appName), repo, util.ColorInfo(url)) 47 } 48 } else { 49 fmt.Fprintf(fileHandles.Out, "Please install '%s' Github App into your organisation/account %s and allow access to repository %s. Click this url \n%s\n\n", util.ColorInfo(appName), owner, repo, util.ColorInfo(url)) 50 } 51 if !accessToRepo { 52 accessToRepo, err = util.Confirm(fmt.Sprintf("Does the '%s' Github App have access to repository", util.ColorInfo(appName)), false, 53 fmt.Sprintf("Please install '%s' Github App into your organisation and grant access to repositories", util.ColorInfo(appName)), fileHandles) 54 if err != nil { 55 return false, err 56 } 57 } 58 if !accessToRepo { 59 return false, errors.New(fmt.Sprintf("Please install '%s' Github App", util.ColorInfo(appName))) 60 } 61 return accessToRepo, err 62 } 63 64 func (gh *GithubApp) isInstalled(owner string, repo string) (bool, bool, string, string, error) { 65 requirementConfig, err := gh.getRequirementConfig() 66 if err != nil { 67 return false, false, "", "", err 68 } 69 70 if requirementConfig.GithubApp != nil { 71 url := requirementConfig.GithubApp.URL + "/installed/" + owner + "/" + repo 72 73 if url != "" { 74 respBody, err := util.CallWithExponentialBackOff(url, "", "GET", []byte{}, nil) 75 log.Logger().Debug(string(respBody)) 76 if err != nil { 77 return false, false, "", "", errors.Wrapf(err, "error getting response from github app via %s", url) 78 } 79 80 response := &response{} 81 82 err = json.Unmarshal(respBody, response) 83 84 if err != nil { 85 return false, false, "", "", errors.Wrapf(err, "error marshalling response %s", url) 86 } 87 return response.Installed, response.AccessToRepo, response.URL, response.AppName, nil 88 } 89 } 90 return false, false, "", "", errors.New("unable to locate github app ") 91 } 92 93 func (gh *GithubApp) getRequirementConfig() (*config.RequirementsConfig, error) { 94 jxClient, ns, err := gh.Factory.CreateJXClient() 95 if err != nil { 96 log.Logger().Errorf("error creating jx client %v", err) 97 return nil, err 98 } 99 100 teamSettings, err := kube.GetDevEnvTeamSettings(jxClient, ns) 101 if err != nil { 102 log.Logger().Errorf("error getting team settings from jx client %v", err) 103 return nil, err 104 } 105 106 requirementConfig, err := config.GetRequirementsConfigFromTeamSettings(teamSettings) 107 if err != nil { 108 log.Logger().Errorf("error getting requirement config from team settings %v", err) 109 return nil, err 110 } 111 return requirementConfig, nil 112 }