func (command *DestroyPipelineCommand) Execute(args []string) error { pipelineName := command.Pipeline fmt.Printf("!!! this will remove all data for pipeline `%s`\n\n", pipelineName) confirm := false err := interact.NewInteraction("are you sure?").Resolve(&confirm) if err != nil || !confirm { fmt.Println("bailing out") return err } connection, err := rc.TargetConnection(Fly.Target) if err != nil { return err } client := concourse.NewClient(connection) found, err := client.DeletePipeline(pipelineName) if err != nil { return err } if !found { fmt.Printf("`%s` does not exist\n", pipelineName) } else { fmt.Printf("`%s` deleted\n", pipelineName) } return nil }
func newConcourseClient(atcUrl, username, password string) concourse.Client { var transport http.RoundTripper var tlsConfig *tls.Config tlsConfig = &tls.Config{InsecureSkipVerify: getSkipSSLValidation()} transport = &http.Transport{ TLSClientConfig: tlsConfig, Dial: (&net.Dialer{ Timeout: 10 * time.Second, }).Dial, Proxy: http.ProxyFromEnvironment, } client := concourse.NewClient( atcUrl, &http.Client{ Transport: basicAuthTransport{ username: username, password: password, base: transport, }, }, ) return client }
func (command *SetPipelineCommand) Execute(args []string) error { configPath := command.Config templateVariablesFiles := command.VarsFrom pipelineName := command.Pipeline templateVariables := template.Variables{} for _, v := range command.Var { templateVariables[v.Name] = v.Value } connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) return nil } client := concourse.NewClient(connection) webRequestGenerator := rata.NewRequestGenerator(connection.URL(), web.Routes) atcConfig := ATCConfig{ pipelineName: pipelineName, webRequestGenerator: webRequestGenerator, client: client, } atcConfig.Set(configPath, templateVariables, templateVariablesFiles) return nil }
func (command *WatchCommand) Execute(args []string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) return nil } client := concourse.NewClient(connection) build, err := GetBuild(client, command.Job.JobName, command.Build, command.Job.PipelineName) if err != nil { log.Fatalln(err) } eventSource, err := client.BuildEvents(fmt.Sprintf("%d", build.ID)) if err != nil { log.Println("failed to attach to stream:", err) os.Exit(1) } exitCode := eventstream.Render(os.Stdout, eventSource) eventSource.Close() os.Exit(exitCode) return nil }
func (command *WorkersCommand) Execute([]string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) } client := concourse.NewClient(connection) workers, err := client.ListWorkers() if err != nil { log.Fatalln(err) } headers := ui.TableRow{ {Contents: "name", Color: color.New(color.Bold)}, {Contents: "containers", Color: color.New(color.Bold)}, {Contents: "platform", Color: color.New(color.Bold)}, {Contents: "tags", Color: color.New(color.Bold)}, } if command.Details { headers = append(headers, ui.TableCell{Contents: "garden address", Color: color.New(color.Bold)}, ui.TableCell{Contents: "baggageclaim url", Color: color.New(color.Bold)}, ui.TableCell{Contents: "resource types", Color: color.New(color.Bold)}, ) } table := ui.Table{Headers: headers} sort.Sort(byWorkerName(workers)) for _, w := range workers { row := ui.TableRow{ {Contents: w.Name}, {Contents: strconv.Itoa(w.ActiveContainers)}, {Contents: w.Platform}, stringOrNone(strings.Join(w.Tags, ", ")), } if command.Details { var resourceTypes []string for _, t := range w.ResourceTypes { resourceTypes = append(resourceTypes, t.Type) } row = append(row, ui.TableCell{Contents: w.GardenAddr}) row = append(row, stringOrNone(w.BaggageclaimURL)) row = append(row, stringOrNone(strings.Join(resourceTypes, ", "))) } table.Data = append(table.Data, row) } return table.Render(os.Stdout) }
func (command *LoginCommand) Execute(args []string) error { var connection concourse.Connection var err error if command.ATCURL != "" { connection, err = rc.NewConnection(command.ATCURL, command.Insecure) } else { connection, err = rc.CommandTargetConnection(Fly.Target, &command.Insecure) } if err != nil { return err } client := concourse.NewClient(connection) authMethods, err := client.ListAuthMethods() if err != nil { return err } var chosenMethod atc.AuthMethod switch len(authMethods) { case 0: fmt.Println("no auth methods configured; updating target data") err := rc.SaveTarget( Fly.Target, connection.URL(), command.Insecure, &rc.TargetToken{}, ) if err != nil { return err } return nil case 1: chosenMethod = authMethods[0] default: choices := make([]interact.Choice, len(authMethods)) for i, method := range authMethods { choices[i] = interact.Choice{ Display: method.DisplayName, Value: method, } } err = interact.NewInteraction("choose an auth method", choices...).Resolve(&chosenMethod) if err != nil { return err } } return command.loginWith(chosenMethod, connection) }
func (cf *clientFactory) Build(r *http.Request) concourse.Client { transport := authorizationTransport{ Authorization: r.Header.Get("Authorization"), Base: &http.Transport{ // disable connection pooling DisableKeepAlives: true, }, } httpClient := &http.Client{ Transport: transport, } return concourse.NewClient(cf.apiEndpoint, httpClient) }
func (command *ContainersCommand) Execute([]string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) } client := concourse.NewClient(connection) containers, err := client.ListContainers(map[string]string{}) if err != nil { log.Fatalln(err) } table := ui.Table{ Headers: ui.TableRow{ {Contents: "handle", Color: color.New(color.Bold)}, {Contents: "worker", Color: color.New(color.Bold)}, {Contents: "pipeline", Color: color.New(color.Bold)}, {Contents: "job", Color: color.New(color.Bold)}, {Contents: "build #", Color: color.New(color.Bold)}, {Contents: "build id", Color: color.New(color.Bold)}, {Contents: "type", Color: color.New(color.Bold)}, {Contents: "name", Color: color.New(color.Bold)}, {Contents: "attempt", Color: color.New(color.Bold)}, }, } sort.Sort(containersByHandle(containers)) for _, c := range containers { row := ui.TableRow{ {Contents: c.ID}, {Contents: c.WorkerName}, stringOrDefault(c.PipelineName), stringOrDefault(c.JobName), stringOrDefault(c.BuildName), buildIDOrNone(c.BuildID), stringOrDefault(c.StepType, "check"), {Contents: (c.StepName + c.ResourceName)}, stringOrDefault(SliceItoa(c.Attempts), "n/a"), } table.Data = append(table.Data, row) } return table.Render(os.Stdout) }
func (command *GetPipelineCommand) Execute(args []string) error { asJSON := command.JSON pipelineName := command.Pipeline connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) } client := concourse.NewClient(connection) config, _, _, err := client.PipelineConfig(pipelineName) if err != nil { log.Fatalln(err) } dump(config, asJSON) return nil }
func (command *ChecklistCommand) Execute([]string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) } pipelineName := command.Pipeline client := concourse.NewClient(connection) config, _, _, err := client.PipelineConfig(pipelineName) if err != nil { log.Fatalln(err) } printCheckfile(pipelineName, config, connection.URL()) return nil }
func CommandTargetClient(selectedTarget TargetName, commandInsecure *bool) (concourse.Client, error) { target, err := SelectTarget(selectedTarget) if err != nil { return nil, err } var token *oauth2.Token if target.Token != nil { token = &oauth2.Token{ TokenType: target.Token.Type, AccessToken: target.Token.Value, } } var tlsConfig *tls.Config if commandInsecure != nil { tlsConfig = &tls.Config{InsecureSkipVerify: *commandInsecure} } else if target.Insecure { tlsConfig = &tls.Config{InsecureSkipVerify: true} } var transport http.RoundTripper transport = &http.Transport{ TLSClientConfig: tlsConfig, Dial: (&net.Dialer{ Timeout: 10 * time.Second, }).Dial, Proxy: http.ProxyFromEnvironment, } if token != nil { transport = &oauth2.Transport{ Source: oauth2.StaticTokenSource(token), Base: transport, } } httpClient := &http.Client{ Transport: transport, } return concourse.NewClient(target.API, httpClient), nil }
func (command *ContainersCommand) Execute([]string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) } client := concourse.NewClient(connection) containers, err := client.ListContainers(map[string]string{}) if err != nil { log.Fatalln(err) } table := ui.Table{ Headers: ui.TableRow{ {Contents: "handle", Color: color.New(color.Bold)}, {Contents: "name", Color: color.New(color.Bold)}, {Contents: "pipeline", Color: color.New(color.Bold)}, {Contents: "type", Color: color.New(color.Bold)}, {Contents: "build id", Color: color.New(color.Bold)}, {Contents: "worker", Color: color.New(color.Bold)}, }, } sort.Sort(containersByHandle(containers)) for _, c := range containers { row := ui.TableRow{ {Contents: c.ID}, {Contents: c.Name}, {Contents: c.PipelineName}, {Contents: c.Type}, buildIDOrNone(c.BuildID), {Contents: c.WorkerName}, } table.Data = append(table.Data, row) } return table.Render(os.Stdout) }
func (command *UnpausePipelineCommand) Execute(args []string) error { pipelineName := command.Pipeline connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) return nil } client := concourse.NewClient(connection) found, err := client.UnpausePipeline(pipelineName) if err != nil { return err } if found { fmt.Printf("unpaused '%s'\n", pipelineName) } else { failf("pipeline '%s' not found\n", pipelineName) } return nil }
func getContainerIDs(c *HijackCommand) []atc.Container { var pipelineName string if c.Job.PipelineName != "" { pipelineName = c.Job.PipelineName } else { pipelineName = c.Check.PipelineName } buildNameOrID := c.Build stepName := c.StepName jobName := c.Job.JobName check := c.Check.ResourceName attempt := c.Attempt fingerprint := containerFingerprint{ pipelineName: pipelineName, jobName: jobName, buildNameOrID: buildNameOrID, stepName: stepName, checkName: check, attempt: attempt, } connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln("failed to create client:", err) } client := concourse.NewClient(connection) reqValues, err := locateContainer(client, fingerprint) if err != nil { log.Fatalln(err) } containers, err := client.ListContainers(reqValues) if err != nil { log.Fatalln("failed to get containers:", err) } return containers }
func NewUnauthenticatedClient(atcURL string, insecure bool) concourse.Client { var tlsConfig *tls.Config if insecure { tlsConfig = &tls.Config{InsecureSkipVerify: insecure} } var transport http.RoundTripper transport = &http.Transport{ TLSClientConfig: tlsConfig, Dial: (&net.Dialer{ Timeout: 10 * time.Second, }).Dial, Proxy: http.ProxyFromEnvironment, } client := concourse.NewClient(atcURL, &http.Client{ Transport: transport, }) return client }
func (command *VolumesCommand) Execute([]string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) } client := concourse.NewClient(connection) volumes, err := client.ListVolumes() if err != nil { log.Fatalln(err) } table := ui.Table{ Headers: ui.TableRow{ {Contents: "handle", Color: color.New(color.Bold)}, {Contents: "ttl", Color: color.New(color.Bold)}, {Contents: "validity", Color: color.New(color.Bold)}, {Contents: "worker", Color: color.New(color.Bold)}, {Contents: "version", Color: color.New(color.Bold)}, }, } sort.Sort(volumesByWorkerAndHandle(volumes)) for _, c := range volumes { row := ui.TableRow{ {Contents: c.ID}, {Contents: formatTTL(c.TTLInSeconds)}, {Contents: formatTTL(c.ValidityInSeconds)}, {Contents: c.WorkerName}, versionCell(c.ResourceVersion), } table.Data = append(table.Data, row) } return table.Render(os.Stdout) }
func (cf *clientFactory) Build(r *http.Request) concourse.Client { transport := authorizationTransport{ Authorization: r.Header.Get("Authorization"), Base: &http.Transport{ // disable connection pooling DisableKeepAlives: true, }, } httpClient := &http.Client{ Transport: transport, } connection, err := concourse.NewConnection(cf.apiEndpoint, httpClient) if err != nil { // TODO really just shouldn't have this error case in the first place panic(err) } return concourse.NewClient(connection) }
func (command *PipelinesCommand) Execute([]string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) return nil } client := concourse.NewClient(connection) pipelines, err := client.ListPipelines() if err != nil { log.Fatalln(err) } table := ui.Table{ Headers: ui.TableRow{ {Contents: "name", Color: color.New(color.Bold)}, {Contents: "paused", Color: color.New(color.Bold)}, }, } for _, p := range pipelines { var pausedColumn ui.TableCell if p.Paused { pausedColumn.Contents = "yes" pausedColumn.Color = color.New(color.FgCyan) } else { pausedColumn.Contents = "no" } table.Data = append(table.Data, []ui.TableCell{ {Contents: p.Name}, pausedColumn, }) } return table.Render(os.Stdout) }
func (command *SyncCommand) Execute(args []string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) return nil } client := concourse.NewClient(connection) body, err := client.GetCLIReader(runtime.GOARCH, runtime.GOOS) if err != nil { log.Fatalln(err) } fmt.Printf("downloading fly from %s... ", connection.URL()) err = update.Apply(body, update.Options{}) if err != nil { failf("update failed: %s", err) } fmt.Println("update successful!") return nil }
func (command *LoginCommand) loginWith(method atc.AuthMethod, client concourse.Client) error { var token atc.AuthToken switch method.Type { case atc.AuthTypeOAuth: fmt.Println("navigate to the following URL in your browser:") fmt.Println("") fmt.Printf(" %s\n", method.AuthURL) fmt.Println("") for { var tokenStr string err := interact.NewInteraction("enter token").Resolve(interact.Required(&tokenStr)) if err != nil { return err } segments := strings.SplitN(tokenStr, " ", 2) if len(segments) != 2 { fmt.Println("token must be of the format 'TYPE VALUE', e.g. 'Bearer ...'") continue } token.Type = segments[0] token.Value = segments[1] break } case atc.AuthTypeBasic: var username string if command.Username != "" { username = command.Username } else { err := interact.NewInteraction("username").Resolve(interact.Required(&username)) if err != nil { return err } } var password string if command.Password != "" { password = command.Password } else { var interactivePassword interact.Password err := interact.NewInteraction("password").Resolve(interact.Required(&interactivePassword)) if err != nil { return err } password = string(interactivePassword) } newUnauthedClient := rc.NewUnauthenticatedClient(client.URL(), command.Insecure) basicAuthClient := concourse.NewClient( newUnauthedClient.URL(), &http.Client{ Transport: basicAuthTransport{ username: username, password: password, base: newUnauthedClient.HTTPClient().Transport, }, }, ) var err error token, err = basicAuthClient.AuthToken() if err != nil { return err } } return command.saveTarget( client.URL(), &rc.TargetToken{ Type: token.Type, Value: token.Value, }, ) }
func TestApi(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Concourse Client Suite") } var ( atcServer *ghttp.Server client concourse.Client team concourse.Team ) var _ = BeforeEach(func() { atcServer = ghttp.NewServer() client = concourse.NewClient( atcServer.URL(), &http.Client{}, ) team = client.Team("some-team") }) var _ = AfterEach(func() { atcServer.Close() }) func Change(fn func() int) *changeMatcher { return &changeMatcher{ fn: fn, } }
func (command *BuildsCommand) Execute([]string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) return nil } client := concourse.NewClient(connection) page := concourse.Page{Limit: command.Count} var builds []atc.Build if command.Job.PipelineName != "" && command.Job.JobName != "" { var found bool builds, _, found, err = client.JobBuilds( command.Job.PipelineName, command.Job.JobName, page, ) if err != nil { log.Fatalln(err) } if !found { log.Fatalln("pipleline/job not found") } } else { builds, _, err = client.Builds(page) if err != nil { log.Fatalln(err) } } table := ui.Table{ Headers: ui.TableRow{ {Contents: "id", Color: color.New(color.Bold)}, {Contents: "pipeline/job", Color: color.New(color.Bold)}, {Contents: "build", Color: color.New(color.Bold)}, {Contents: "status", Color: color.New(color.Bold)}, {Contents: "start", Color: color.New(color.Bold)}, {Contents: "end", Color: color.New(color.Bold)}, {Contents: "duration", Color: color.New(color.Bold)}, }, } var rangeUntil int if command.Count < len(builds) { rangeUntil = command.Count } else { rangeUntil = len(builds) } for _, b := range builds[:rangeUntil] { startTimeCell, endTimeCell, durationCell := populateTimeCells(time.Unix(b.StartTime, 0), time.Unix(b.EndTime, 0)) var pipelineJobCell, buildCell ui.TableCell if b.PipelineName == "" { pipelineJobCell.Contents = "one-off" buildCell.Contents = "n/a" } else { pipelineJobCell.Contents = fmt.Sprintf("%s/%s", b.PipelineName, b.JobName) buildCell.Contents = b.Name } var statusCell ui.TableCell statusCell.Contents = b.Status switch b.Status { case "pending": statusCell.Color = ui.PendingColor case "started": statusCell.Color = ui.StartedColor case "succeeded": statusCell.Color = ui.SucceededColor case "failed": statusCell.Color = ui.FailedColor case "errored": statusCell.Color = ui.ErroredColor case "aborted": statusCell.Color = ui.AbortedColor case "paused": statusCell.Color = ui.PausedColor } table.Data = append(table.Data, []ui.TableCell{ {Contents: strconv.Itoa(b.ID)}, pipelineJobCell, buildCell, statusCell, startTimeCell, endTimeCell, durationCell, }) } return table.Render(os.Stdout) }
func (command *LoginCommand) loginWith(method atc.AuthMethod, connection concourse.Connection) error { var token atc.AuthToken switch method.Type { case atc.AuthTypeOAuth: fmt.Println("navigate to the following URL in your browser:") fmt.Println("") fmt.Printf(" %s\n", method.AuthURL) fmt.Println("") for { var tokenStr string err := interact.NewInteraction("enter token").Resolve(interact.Required(&tokenStr)) if err != nil { return err } segments := strings.SplitN(tokenStr, " ", 2) if len(segments) != 2 { fmt.Println("token must be of the format 'TYPE VALUE', e.g. 'Bearer ...'") continue } token.Type = segments[0] token.Value = segments[1] break } case atc.AuthTypeBasic: var username string err := interact.NewInteraction("username").Resolve(interact.Required(&username)) if err != nil { return err } var password interact.Password err = interact.NewInteraction("password").Resolve(interact.Required(&password)) if err != nil { return err } newUnauthedClient, err := rc.NewConnection(connection.URL(), command.Insecure) if err != nil { return err } basicAuthClient, err := concourse.NewConnection( newUnauthedClient.URL(), &http.Client{ Transport: basicAuthTransport{ username: username, password: string(password), base: newUnauthedClient.HTTPClient().Transport, }, }, ) if err != nil { return err } client := concourse.NewClient(basicAuthClient) token, err = client.AuthToken() if err != nil { return err } } err := rc.SaveTarget( Fly.Target, connection.URL(), command.Insecure, &rc.TargetToken{ Type: token.Type, Value: token.Value, }, ) if err != nil { return err } fmt.Println("token saved") return nil }
func (command *ExecuteCommand) Execute(args []string) error { connection, err := rc.TargetConnection(Fly.Target) if err != nil { log.Fatalln(err) return nil } client := concourse.NewClient(connection) taskConfigFile := command.TaskConfig excludeIgnored := command.ExcludeIgnored atcRequester := deprecated.NewAtcRequester(connection.URL(), connection.HTTPClient()) taskConfig := config.LoadTaskConfig(string(taskConfigFile), args) inputs, err := executehelpers.DetermineInputs( client, taskConfig.Inputs, command.Inputs, command.InputsFrom, ) if err != nil { return err } outputs, err := executehelpers.DetermineOutputs( client, taskConfig.Outputs, command.Outputs, ) if err != nil { return err } build, err := executehelpers.CreateBuild( atcRequester, client, command.Privileged, inputs, outputs, taskConfig, command.Tags, Fly.Target, ) if err != nil { return err } fmt.Println("executing build", build.ID) terminate := make(chan os.Signal, 1) go abortOnSignal(client, terminate, build) signal.Notify(terminate, syscall.SIGINT, syscall.SIGTERM) inputChan := make(chan interface{}) go func() { for _, i := range inputs { if i.Path != "" { executehelpers.Upload(i, excludeIgnored, atcRequester) } } close(inputChan) }() var outputChans []chan (interface{}) if len(outputs) > 0 { for i, output := range outputs { outputChans = append(outputChans, make(chan interface{}, 1)) go func(o executehelpers.Output, outputChan chan<- interface{}) { if o.Path != "" { executehelpers.Download(o, atcRequester) } close(outputChan) }(output, outputChans[i]) } } eventSource, err := client.BuildEvents(fmt.Sprintf("%d", build.ID)) if err != nil { log.Println("failed to attach to stream:", err) os.Exit(1) } exitCode := eventstream.Render(os.Stdout, eventSource) eventSource.Close() <-inputChan if len(outputs) > 0 { for _, outputChan := range outputChans { <-outputChan } } os.Exit(exitCode) return nil }
func (command *LoginCommand) Execute(args []string) error { if isURL(Fly.Target) { return errors.New("name for the target must be specified (--target/-t)") } var connection concourse.Connection var err error if command.ATCURL != "" { connection, err = rc.NewConnection(command.ATCURL, command.Insecure) } else { connection, err = rc.CommandTargetConnection(Fly.Target, &command.Insecure) } if err != nil { return err } client := concourse.NewClient(connection) authMethods, err := client.ListAuthMethods() if err != nil { return err } var chosenMethod atc.AuthMethod if command.Username != "" && command.Password != "" { for _, method := range authMethods { if method.Type == atc.AuthTypeBasic { chosenMethod = method break } } if chosenMethod.Type == "" { return errors.New("basic auth is not available") } } else { switch len(authMethods) { case 0: return command.saveTarget( connection.URL(), &rc.TargetToken{}, ) case 1: chosenMethod = authMethods[0] default: choices := make([]interact.Choice, len(authMethods)) for i, method := range authMethods { choices[i] = interact.Choice{ Display: method.DisplayName, Value: method, } } err = interact.NewInteraction("choose an auth method", choices...).Resolve(&chosenMethod) if err != nil { return err } } } return command.loginWith(chosenMethod, connection) }