Skip to content

Commit

Permalink
fly: behaviour: add archive-pipeline command
Browse files Browse the repository at this point in the history
#5320

Adds an archive-pipeline command that functions nearly identically to
pause-pipeline

Signed-off-by: Aidan Oldershaw <aoldershaw@pivotal.io>
Co-authored-by: James Thomson <jthomson@pivotal.io>
  • Loading branch information
aoldershaw and James Thomson committed Mar 30, 2020
1 parent d2a5159 commit c292309
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 0 deletions.
76 changes: 76 additions & 0 deletions fly/commands/archive_pipeline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package commands

import (
"fmt"

"github.com/concourse/concourse/fly/commands/internal/displayhelpers"
"github.com/concourse/concourse/fly/commands/internal/flaghelpers"
"github.com/concourse/concourse/fly/rc"
)

type ArchivePipelineCommand struct {
Pipeline flaghelpers.PipelineFlag `short:"p" long:"pipeline" description:"Pipeline to archive"`
All bool `short:"a" long:"all" description:"Archive all pipelines"`
}

func (command *ArchivePipelineCommand) Validate() error {
return command.Pipeline.Validate()
}

func (command *ArchivePipelineCommand) Execute(args []string) error {
if string(command.Pipeline) == "" && !command.All {
displayhelpers.Failf("Either a pipeline name or --all are required")
}

if string(command.Pipeline) != "" && command.All {
displayhelpers.Failf("A pipeline and --all can not both be specified")
}

err := command.Validate()
if err != nil {
return err
}

target, err := rc.LoadTarget(Fly.Target, Fly.Verbose)
if err != nil {
return err
}

err = target.Validate()
if err != nil {
return err
}

var pipelineNames []string
if string(command.Pipeline) != "" {
pipelineNames = []string{string(command.Pipeline)}
}

if command.All {
pipelines, err := target.Team().ListPipelines()
if err != nil {
return err
}

for _, pipeline := range pipelines {
if !pipeline.Archived {
pipelineNames = append(pipelineNames, pipeline.Name)
}
}
}

for _, pipelineName := range pipelineNames {
found, err := target.Team().ArchivePipeline(pipelineName)
if err != nil {
return err
}

if found {
fmt.Printf("archived '%s'\n", pipelineName)
} else {
displayhelpers.Failf("pipeline '%s' not found\n", pipelineName)
}
}

return nil
}
1 change: 1 addition & 0 deletions fly/commands/fly.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type FlyCommand struct {
GetPipeline GetPipelineCommand `command:"get-pipeline" alias:"gp" description:"Get a pipeline's current configuration"`
SetPipeline SetPipelineCommand `command:"set-pipeline" alias:"sp" description:"Create or update a pipeline's configuration"`
PausePipeline PausePipelineCommand `command:"pause-pipeline" alias:"pp" description:"Pause a pipeline"`
ArchivePipeline ArchivePipelineCommand `command:"archive-pipeline" alias:"ap" description:"Archive a pipeline"`
UnpausePipeline UnpausePipelineCommand `command:"unpause-pipeline" alias:"up" description:"Un-pause a pipeline"`
ExposePipeline ExposePipelineCommand `command:"expose-pipeline" alias:"ep" description:"Make a pipeline publicly viewable"`
HidePipeline HidePipelineCommand `command:"hide-pipeline" alias:"hp" description:"Hide a pipeline from the public"`
Expand Down
188 changes: 188 additions & 0 deletions fly/integration/archive_pipeline_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package integration_test

import (
"net/http"
"os/exec"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"github.com/concourse/concourse/atc"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"github.com/onsi/gomega/ghttp"
"github.com/tedsuo/rata"
)

var _ = Describe("Fly CLI", func() {
Describe("archive-pipeline", func() {
Context("when the pipeline name is specified", func() {
var (
path string
err error
)
BeforeEach(func() {
path, err = atc.Routes.CreatePathForRoute(atc.ArchivePipeline, rata.Params{"pipeline_name": "awesome-pipeline", "team_name": "main"})
Expect(err).NotTo(HaveOccurred())
})

Context("when the pipeline exists", func() {
BeforeEach(func() {
atcServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", path),
ghttp.RespondWith(http.StatusOK, nil),
),
)
})

It("archives the pipeline", func() {
Expect(func() {
flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "awesome-pipeline")

sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(sess).Should(gbytes.Say(`archived 'awesome-pipeline'`))

<-sess.Exited
Expect(sess.ExitCode()).To(Equal(0))
}).To(Change(func() int {
return len(atcServer.ReceivedRequests())
}).By(2))
})
})

Context("when the pipeline doesn't exist", func() {
BeforeEach(func() {
atcServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", path),
ghttp.RespondWith(http.StatusNotFound, nil),
),
)
})

It("prints helpful message", func() {
Expect(func() {
flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "awesome-pipeline")

sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(sess.Err).Should(gbytes.Say(`pipeline 'awesome-pipeline' not found`))

<-sess.Exited
Expect(sess.ExitCode()).To(Equal(1))
}).To(Change(func() int {
return len(atcServer.ReceivedRequests())
}).By(2))
})
})
})

Context("when the pipeline name or --all is not specified", func() {
It("errors", func() {
Expect(func() {
flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline")

sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(sess.Err).Should(gbytes.Say(`Either a pipeline name or --all are required`))

<-sess.Exited
Expect(sess.ExitCode()).To(Equal(1))
}).To(Change(func() int {
return len(atcServer.ReceivedRequests())
}).By(0))
})
})

Context("when both the pipeline name and --all are specified", func() {
It("errors", func() {
Expect(func() {
flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "awesome-pipeline", "--all")

sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(sess.Err).Should(gbytes.Say(`A pipeline and --all can not both be specified`))

<-sess.Exited
Expect(sess.ExitCode()).To(Equal(1))
}).To(Change(func() int {
return len(atcServer.ReceivedRequests())
}).By(0))
})
})

Context("when specifying a pipeline name with a '/' character in it", func() {
It("fails and says '/' characters are not allowed", func() {
flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "forbidden/pipelinename")

sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

<-sess.Exited
Expect(sess.ExitCode()).To(Equal(1))

Expect(sess.Err).To(gbytes.Say("error: pipeline name cannot contain '/'"))
})
})

})

Context("when the --all flag is passed", func() {
var (
somePath string
someOtherPath string
err error
)

BeforeEach(func() {
somePath, err = atc.Routes.CreatePathForRoute(atc.ArchivePipeline, rata.Params{"pipeline_name": "awesome-pipeline", "team_name": "main"})
Expect(err).NotTo(HaveOccurred())

someOtherPath, err = atc.Routes.CreatePathForRoute(atc.ArchivePipeline, rata.Params{"pipeline_name": "more-awesome-pipeline", "team_name": "main"})
Expect(err).NotTo(HaveOccurred())

atcServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"),
ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{
{Name: "awesome-pipeline", Archived: false, Public: false},
{Name: "more-awesome-pipeline", Archived: false, Public: false},
{Name: "already-archived", Archived: true, Public: false},
}),
),
ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", somePath),
ghttp.RespondWith(http.StatusOK, nil),
),
ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", someOtherPath),
ghttp.RespondWith(http.StatusOK, nil),
),
)
})

It("archives every currently unarchived pipeline", func() {
Expect(func() {
flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "--all")

sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(sess).Should(gbytes.Say(`archived 'awesome-pipeline'`))
Eventually(sess).Should(gbytes.Say(`archived 'more-awesome-pipeline'`))
Consistently(sess).ShouldNot(gbytes.Say(`archived 'already-archived'`))

<-sess.Exited
Expect(sess.ExitCode()).To(Equal(0))
}).To(Change(func() int {
return len(atcServer.ReceivedRequests())
}).By(4))
})
})
})

0 comments on commit c292309

Please sign in to comment.