func ValidateClient(client concourse.Client, targetName TargetName) error { info, err := client.GetInfo() if err != nil { return err } if info.Version == version.Version || version.IsDev(version.Version) { return nil } atcMajor, atcMinor, atcPatch, err := version.GetSemver(info.Version) if err != nil { return err } flyMajor, flyMinor, flyPatch, err := version.GetSemver(version.Version) if err != nil { return err } if ((atcMajor == flyMajor) && (atcMinor != flyMinor)) || (atcMajor != flyMajor) { return NewErrVersionMismatch(version.Version, info.Version, targetName) } if (atcMajor == flyMajor) && (atcMinor == flyMinor) && (atcPatch != flyPatch) { fmt.Fprintln(os.Stderr, ui.WarningColor("WARNING:\n")) fmt.Fprintln(os.Stderr, ui.WarningColor(NewErrVersionMismatch(version.Version, info.Version, targetName).Error())) } return nil }
func Download(client concourse.Client, output Output) { path := output.Path pipe := output.Pipe response, err := client.HTTPClient().Get(pipe.ReadURL) if err != nil { fmt.Fprintln(os.Stderr, "download request failed:", err) } defer response.Body.Close() if response.StatusCode != http.StatusOK { fmt.Fprintln(os.Stderr, badResponseError("downloading bits", response)) panic("unexpected-response-code") } err = os.MkdirAll(path, 0755) if err != nil { panic(err) } err = tarStreamTo(path, response.Body) if err != nil { panic(err) } }
func FetchTemplateData(client concourse.Client) (TemplateData, error) { builds, err := client.AllBuilds() if err != nil { return TemplateData{}, err } return TemplateData{ Builds: PresentBuilds(builds), }, nil }
func FetchTemplateData(client concourse.Client, page concourse.Page) (TemplateData, error) { builds, pagination, err := client.Builds(page) if err != nil { return TemplateData{}, err } return TemplateData{ Builds: PresentBuilds(builds), Pagination: pagination, }, nil }
func FetchTemplateData(buildID string, client concourse.Client) (TemplateData, error) { build, found, err := client.Build(buildID) if err != nil { return TemplateData{}, err } if !found { return TemplateData{}, ErrBuildNotFound } return TemplateData{Build: build}, nil }
func GetBuild(client concourse.Client, jobName string, buildNameOrID string, pipelineName string) (atc.Build, error) { if buildNameOrID != "" { var build atc.Build var err error var found bool if jobName != "" { build, found, err = client.JobBuild(pipelineName, jobName, buildNameOrID) } else { build, found, err = client.Build(buildNameOrID) } if err != nil { return atc.Build{}, fmt.Errorf("failed to get build %s", err) } if !found { return atc.Build{}, errors.New("build not found") } return build, nil } else if jobName != "" { job, found, err := client.Job(pipelineName, jobName) if err != nil { return atc.Build{}, fmt.Errorf("failed to get job %s", err) } if !found { return atc.Build{}, errors.New("job not found") } if job.NextBuild != nil { return *job.NextBuild, nil } else if job.FinishedBuild != nil { return *job.FinishedBuild, nil } else { return atc.Build{}, errors.New("job has no builds") } } else { page := &concourse.Page{Limit: 100} for page != nil { allBuilds, pagination, err := client.Builds(*page) if err != nil { return atc.Build{}, fmt.Errorf("failed to get builds %s", err) } for _, build := range allBuilds { if build.JobName == "" { return build, nil } } page = pagination.Next } return atc.Build{}, errors.New("no builds match job") } }
func getAllJobBuilds(client concourse.Client, pipelineName string, jobName string) ([]atc.Build, error) { builds := []atc.Build{} page := &concourse.Page{} for page != nil { bs, pagination, _, err := client.JobBuilds(pipelineName, jobName, *page) if err != nil { return nil, err } builds = append(builds, bs...) page = pagination.Next } return builds, nil }
func Upload(client concourse.Client, input Input, excludeIgnored bool) { path := input.Path pipe := input.Pipe var files []string var err error if excludeIgnored { files, err = getGitFiles(path) if err != nil { fmt.Fprintln(os.Stderr, "could not determine ignored files:", err) return } } else { files = []string{"."} } archive, err := tarStreamFrom(path, files) if err != nil { fmt.Fprintln(os.Stderr, "could create tar stream:", err) return } defer archive.Close() upload, err := http.NewRequest("PUT", pipe.WriteURL, archive) if err != nil { panic(err) } response, err := client.HTTPClient().Do(upload) if err != nil { fmt.Fprintln(os.Stderr, "upload request failed:", err) return } defer response.Body.Close() if response.StatusCode != http.StatusOK { fmt.Fprintln(os.Stderr, badResponseError("uploading bits", response)) } }
func abortOnSignal( client concourse.Client, terminate <-chan os.Signal, build atc.Build, ) { <-terminate fmt.Fprintf(os.Stderr, "\naborting...\n") err := client.AbortBuild(strconv.Itoa(build.ID)) if err != nil { fmt.Fprintln(os.Stderr, "failed to abort:", err) return } // if told to terminate again, exit immediately <-terminate fmt.Fprintln(os.Stderr, "exiting immediately") os.Exit(2) }
func GenerateLocalInputs(client concourse.Client, inputMappings []flaghelpers.InputPairFlag) (map[string]Input, error) { kvMap := map[string]Input{} for _, i := range inputMappings { inputName := i.Name absPath := i.Path pipe, err := client.CreatePipe() if err != nil { return nil, err } kvMap[inputName] = Input{ Name: inputName, Path: absPath, Pipe: pipe, } } return kvMap, nil }
func DetermineOutputs( client concourse.Client, taskOutputs []atc.TaskOutputConfig, outputMappings []flaghelpers.OutputPairFlag, ) ([]Output, error) { outputs := []Output{} for _, i := range outputMappings { outputName := i.Name notInConfig := true for _, configOutput := range taskOutputs { if configOutput.Name == outputName { notInConfig = false } } if notInConfig { return nil, fmt.Errorf("unknown output '%s'", outputName) } absPath, err := filepath.Abs(i.Path) if err != nil { return nil, err } pipe, err := client.CreatePipe() if err != nil { return nil, err } outputs = append(outputs, Output{ Name: outputName, Path: absPath, Pipe: pipe, }) } return outputs, nil }
func FetchInputsFromJob(client concourse.Client, inputsFrom flaghelpers.JobFlag) (map[string]Input, error) { kvMap := map[string]Input{} if inputsFrom.PipelineName == "" && inputsFrom.JobName == "" { return kvMap, nil } buildInputs, found, err := client.BuildInputsForJob(inputsFrom.PipelineName, inputsFrom.JobName) if err != nil { return nil, err } if !found { return nil, errors.New("build inputs not found") } for _, buildInput := range buildInputs { kvMap[buildInput.Name] = Input{ Name: buildInput.Name, BuildInput: buildInput, } } return kvMap, nil }
func CreateBuild( client concourse.Client, privileged bool, inputs []Input, outputs []Output, config atc.TaskConfig, tags []string, target rc.TargetName, ) (atc.Build, error) { fact := atc.NewPlanFactory(time.Now().Unix()) if err := config.Validate(); err != nil { return atc.Build{}, err } targetProps, err := rc.SelectTarget(target) if err != nil { return atc.Build{}, err } buildInputs := atc.AggregatePlan{} for _, input := range inputs { var getPlan atc.GetPlan if input.Path != "" { source := atc.Source{ "uri": input.Pipe.ReadURL, } if auth, ok := targetAuthorization(targetProps.Token); ok { source["authorization"] = auth } getPlan = atc.GetPlan{ Name: input.Name, Type: "archive", Source: source, } } else { getPlan = atc.GetPlan{ Name: input.Name, Type: input.BuildInput.Type, Source: input.BuildInput.Source, Version: input.BuildInput.Version, Params: input.BuildInput.Params, Tags: input.BuildInput.Tags, } } buildInputs = append(buildInputs, fact.NewPlan(getPlan)) } taskPlan := fact.NewPlan(atc.TaskPlan{ Name: "one-off", Privileged: privileged, Config: &config, }) if len(tags) != 0 { taskPlan.Task.Tags = tags } buildOutputs := atc.AggregatePlan{} for _, output := range outputs { source := atc.Source{ "uri": output.Pipe.ReadURL, } params := atc.Params{ "directory": output.Name, } if auth, ok := targetAuthorization(targetProps.Token); ok { source["authorization"] = auth } buildOutputs = append(buildOutputs, fact.NewPlan(atc.PutPlan{ Name: output.Name, Type: "archive", Source: source, Params: params, })) } var plan atc.Plan if len(buildOutputs) == 0 { plan = fact.NewPlan(atc.DoPlan{ fact.NewPlan(buildInputs), taskPlan, }) } else { plan = fact.NewPlan(atc.EnsurePlan{ Step: fact.NewPlan(atc.DoPlan{ fact.NewPlan(buildInputs), taskPlan, }), Next: fact.NewPlan(buildOutputs), }) } return client.CreateBuild(plan) }
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 CreateBuild( atcRequester *deprecated.AtcRequester, client concourse.Client, privileged bool, inputs []Input, outputs []Output, config atc.TaskConfig, tags []string, target string, ) (atc.Build, error) { if err := config.Validate(); err != nil { return atc.Build{}, err } targetProps, err := rc.SelectTarget(target) if err != nil { return atc.Build{}, err } buildInputs := atc.AggregatePlan{} for i, input := range inputs { var getPlan atc.GetPlan if input.Path != "" { readPipe, err := atcRequester.CreateRequest( atc.ReadPipe, rata.Params{"pipe_id": input.Pipe.ID}, nil, ) if err != nil { return atc.Build{}, err } source := atc.Source{ "uri": readPipe.URL.String(), } if targetProps.Token != nil { source["authorization"] = targetProps.Token.Type + " " + targetProps.Token.Value } getPlan = atc.GetPlan{ Name: input.Name, Type: "archive", Source: source, } } else { getPlan = atc.GetPlan{ Name: input.Name, Type: input.BuildInput.Type, Source: input.BuildInput.Source, Version: input.BuildInput.Version, Params: input.BuildInput.Params, Tags: input.BuildInput.Tags, } } buildInputs = append(buildInputs, atc.Plan{ Location: &atc.Location{ // offset by 2 because aggregate gets parallelgroup ID 1 ID: uint(i) + 2, ParentID: 0, ParallelGroup: 1, }, Get: &getPlan, }) } taskPlan := atc.Plan{ Location: &atc.Location{ // offset by 1 because aggregate gets parallelgroup ID 1 ID: uint(len(inputs)) + 2, ParentID: 0, }, Task: &atc.TaskPlan{ Name: "one-off", Privileged: privileged, Config: &config, }, } if len(tags) != 0 { taskPlan.Task.Tags = tags } buildOutputs := atc.AggregatePlan{} for i, output := range outputs { writePipe, err := atcRequester.CreateRequest( atc.WritePipe, rata.Params{"pipe_id": output.Pipe.ID}, nil, ) if err != nil { return atc.Build{}, err } source := atc.Source{ "uri": writePipe.URL.String(), } params := atc.Params{ "directory": output.Name, } if targetProps.Token != nil { source["authorization"] = targetProps.Token.Type + " " + targetProps.Token.Value } buildOutputs = append(buildOutputs, atc.Plan{ Location: &atc.Location{ ID: taskPlan.Location.ID + 2 + uint(i), ParentID: 0, ParallelGroup: taskPlan.Location.ID + 1, }, Put: &atc.PutPlan{ Name: output.Name, Type: "archive", Source: source, Params: params, }, }) } var plan atc.Plan if len(buildOutputs) == 0 { plan = atc.Plan{ OnSuccess: &atc.OnSuccessPlan{ Step: atc.Plan{ Aggregate: &buildInputs, }, Next: taskPlan, }, } } else { plan = atc.Plan{ OnSuccess: &atc.OnSuccessPlan{ Step: atc.Plan{ Aggregate: &buildInputs, }, Next: atc.Plan{ Ensure: &atc.EnsurePlan{ Step: taskPlan, Next: atc.Plan{ Aggregate: &buildOutputs, }, }, }, }, } } return client.CreateBuild(plan) }
func FetchTemplateData( pipelineName string, client concourse.Client, jobName string, page concourse.Page, ) (TemplateData, error) { pipeline, pipelineFound, err := client.Pipeline(pipelineName) if err != nil { return TemplateData{}, err } if !pipelineFound { return TemplateData{}, ErrConfigNotFound } job, jobFound, err := client.Job(pipelineName, jobName) if err != nil { return TemplateData{}, err } if !jobFound { return TemplateData{}, ErrJobConfigNotFound } bs, pagination, _, err := client.JobBuilds(pipelineName, jobName, page) if err != nil { return TemplateData{}, err } var bsr []BuildWithInputsOutputs for _, build := range bs { buildInputsOutputs, _, err := client.BuildResources(build.ID) if err != nil { return TemplateData{}, err } bsr = append(bsr, BuildWithInputsOutputs{ Build: build, Resources: buildInputsOutputs, }) } return TemplateData{ PipelineName: pipelineName, Job: job, Builds: bsr, Pagination: pagination, GroupStates: group.States(pipeline.Groups, func(g atc.GroupConfig) bool { for _, groupJob := range g.Jobs { if groupJob == job.Name { return true } } return false }), CurrentBuild: job.FinishedBuild, }, nil }
func FetchTemplateData(pipelineName string, resourceName string, client concourse.Client, page concourse.Page) (TemplateData, error) { pipeline, pipelineFound, err := client.Pipeline(pipelineName) if err != nil { return TemplateData{}, err } if !pipelineFound { return TemplateData{}, ErrConfigNotFound } resource, resourceFound, err := client.Resource(pipelineName, resourceName) if err != nil { return TemplateData{}, err } if !resourceFound { return TemplateData{}, ErrResourceNotFound } versionedResources, pagination, resourceVersionsFound, err := client.ResourceVersions(pipelineName, resourceName, page) if err != nil { return TemplateData{}, err } if !resourceVersionsFound { return TemplateData{}, ErrResourceNotFound } versions := []VersionedResourceWithInputsAndOutputs{} for _, versionedResource := range versionedResources { inputs, _, err := client.BuildsWithVersionAsInput(pipelineName, resourceName, versionedResource.ID) if err != nil { return TemplateData{}, err } outputs, _, err := client.BuildsWithVersionAsOutput(pipelineName, resourceName, versionedResource.ID) if err != nil { return TemplateData{}, err } inputsTo := map[string][]atc.Build{} outputsOf := map[string][]atc.Build{} for _, input := range inputs { if _, ok := inputsTo[input.JobName]; !ok { inputsTo[input.JobName] = []atc.Build{} } inputsTo[input.JobName] = append(inputsTo[input.JobName], input) } for _, output := range outputs { if _, ok := outputsOf[output.JobName]; !ok { outputsOf[output.JobName] = []atc.Build{} } outputsOf[output.JobName] = append(outputsOf[output.JobName], output) } versions = append(versions, VersionedResourceWithInputsAndOutputs{ VersionedResource: versionedResource, InputsTo: inputsTo, OutputsOf: outputsOf, }) } return TemplateData{ Resource: resource, Versions: versions, PipelineName: pipelineName, Pagination: pagination, GroupStates: group.States(pipeline.Groups, func(g atc.GroupConfig) bool { for _, groupResource := range g.Resources { if groupResource == resource.Name { return true } } return false }), }, nil }
func GetBuild(client concourse.Client, jobName string, buildNameOrID string, pipelineName string) (atc.Build, error) { if pipelineName != "" && jobName == "" { log.Fatalln("job must be specified if pipeline is specified") } if pipelineName == "" && jobName != "" { log.Fatalln("pipeline must be specified if job is specified") } if buildNameOrID != "" { var build atc.Build var err error var found bool if jobName != "" { build, found, err = client.JobBuild(pipelineName, jobName, buildNameOrID) } else { build, found, err = client.Build(buildNameOrID) } if err != nil { return atc.Build{}, fmt.Errorf("failed to get build %s", err) } if !found { return atc.Build{}, errors.New("build not found") } return build, nil } else if jobName != "" { job, found, err := client.Job(pipelineName, jobName) if err != nil { return atc.Build{}, fmt.Errorf("failed to get job %s", err) } if !found { return atc.Build{}, errors.New("job not found") } if job.NextBuild != nil { return *job.NextBuild, nil } else if job.FinishedBuild != nil { return *job.FinishedBuild, nil } else { return atc.Build{}, errors.New("job has no builds") } } else { allBuilds, err := client.AllBuilds() if err != nil { return atc.Build{}, fmt.Errorf("failed to get builds %s", err) } for _, build := range allBuilds { if build.JobName == "" { return build, nil } } return atc.Build{}, errors.New("no builds match job") } }
func CreateBuild( atcRequester *deprecated.AtcRequester, client concourse.Client, privileged bool, inputs []Input, outputs []Output, config atc.TaskConfig, tags []string, target string, ) (atc.Build, error) { fact := atc.NewPlanFactory(time.Now().Unix()) if err := config.Validate(); err != nil { return atc.Build{}, err } targetProps, err := rc.SelectTarget(target) if err != nil { return atc.Build{}, err } buildInputs := atc.AggregatePlan{} for _, input := range inputs { var getPlan atc.GetPlan if input.Path != "" { readPipe, err := atcRequester.CreateRequest( atc.ReadPipe, rata.Params{"pipe_id": input.Pipe.ID}, nil, ) if err != nil { return atc.Build{}, err } source := atc.Source{ "uri": readPipe.URL.String(), } if targetProps.Token != nil { source["authorization"] = targetProps.Token.Type + " " + targetProps.Token.Value } getPlan = atc.GetPlan{ Name: input.Name, Type: "archive", Source: source, } } else { getPlan = atc.GetPlan{ Name: input.Name, Type: input.BuildInput.Type, Source: input.BuildInput.Source, Version: input.BuildInput.Version, Params: input.BuildInput.Params, Tags: input.BuildInput.Tags, } } buildInputs = append(buildInputs, fact.NewPlan(getPlan)) } taskPlan := fact.NewPlan(atc.TaskPlan{ Name: "one-off", Privileged: privileged, Config: &config, }) if len(tags) != 0 { taskPlan.Task.Tags = tags } buildOutputs := atc.AggregatePlan{} for _, output := range outputs { writePipe, err := atcRequester.CreateRequest( atc.WritePipe, rata.Params{"pipe_id": output.Pipe.ID}, nil, ) if err != nil { return atc.Build{}, err } source := atc.Source{ "uri": writePipe.URL.String(), } params := atc.Params{ "directory": output.Name, } if targetProps.Token != nil { source["authorization"] = targetProps.Token.Type + " " + targetProps.Token.Value } buildOutputs = append(buildOutputs, fact.NewPlan(atc.PutPlan{ Name: output.Name, Type: "archive", Source: source, Params: params, })) } var plan atc.Plan if len(buildOutputs) == 0 { plan = fact.NewPlan(atc.DoPlan{ fact.NewPlan(buildInputs), taskPlan, }) } else { plan = fact.NewPlan(atc.DoPlan{ fact.NewPlan(buildInputs), fact.NewPlan(atc.EnsurePlan{ Step: taskPlan, Next: fact.NewPlan(buildOutputs), }), }) } return client.CreateBuild(plan) }
"github.com/concourse/go-concourse/concourse" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/ghttp" "testing" ) 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() {
func (command *LoginCommand) Execute(args []string) error { if Fly.Target == "" { return errors.New("name for the target must be specified (--target/-t)") } var client concourse.Client var err error if command.ATCURL != "" { client = rc.NewUnauthenticatedClient(command.ATCURL, command.Insecure) } else { client, err = rc.CommandTargetClient(Fly.Target, &command.Insecure) } if err != nil { return err } err = rc.ValidateClient(client, Fly.Target) if err != nil { return err } 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( client.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, client) }