Skip to content

Commit

Permalink
bosh take-out
Browse files Browse the repository at this point in the history
  • Loading branch information
metron2 committed Jun 11, 2021
1 parent 3c1a893 commit 8e6a507
Show file tree
Hide file tree
Showing 9 changed files with 635 additions and 1 deletion.
4 changes: 4 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"github.com/cloudfoundry/bosh-cli/takeout"
"path/filepath"

"github.com/cppforlife/go-patch/patch"
Expand Down Expand Up @@ -155,6 +156,9 @@ func (c Cmd) Execute() (cmdErr error) {
case *DeleteDeploymentOpts:
return NewDeleteDeploymentCmd(deps.UI, c.deployment()).Run(*opts)

case *TakeOutOpts:
return NewTakeOutCmd(deps.UI, takeout.RealUtensils{}).Run(*opts)

case *ReleasesOpts:
return NewReleasesCmd(deps.UI, c.director()).Run()

Expand Down
22 changes: 21 additions & 1 deletion cmd/opts/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type BoshOpts struct {
Manifest ManifestOpts `command:"manifest" alias:"man" description:"Show deployment manifest"`

Interpolate InterpolateOpts `command:"interpolate" alias:"int" description:"Interpolates variables into a manifest"`
TakeOut TakeOutOpts `command:"take-out" description:"prepares dependencies for offline use"`

// Events
Events EventsOpts `command:"events" description:"List events"`
Expand Down Expand Up @@ -281,7 +282,7 @@ type TaskOpts struct {
Event bool `long:"event" description:"Track event log"`
CPI bool `long:"cpi" description:"Track CPI log"`
Debug bool `long:"debug" description:"Track debug log"`
Result bool `long:"result" description:"Track result log"`
Result bool `longTake:"result" description:"Track result log"`

All bool `long:"all" short:"a" description:"Include all task types (ssh, logs, vms, etc)"`
Deployment string
Expand Down Expand Up @@ -358,6 +359,25 @@ type InterpolateArgs struct {
Manifest FileBytesArg `positional-arg-name:"PATH" description:"Path to a template that will be interpolated"`
}

type TakeOutOpts struct {
Args TakeOutArgs `positional-args:"true" required:"true"`
MirrorPrefix string `long:"mirror-prefix" short:"m" description:"Mirror prefix" optional:"true" default:"file:"`
StemcellType string `long:"stemcell-type" short:"t" description:"Stemcell type" optional:"true" default:"vsphere-esxi"`

VarFlags
OpsFlags

VarErrors bool `long:"var-errs" description:"Expect all variables to be found, otherwise error"`
VarErrorsUnused bool `long:"var-errs-unused" description:"Expect all variables to be used, otherwise error"`

cmd
}

type TakeOutArgs struct {
Name string `positional-arg-name:"NAME" description:"file name of ops file"`
Manifest FileBytesArg `positional-arg-name:"PATH" description:"Path to a template for take_out"`
}

// Config

type ConfigOpts struct {
Expand Down
54 changes: 54 additions & 0 deletions cmd/opts/opts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,60 @@ var _ = Describe("Opts", func() {
})
})

Describe("TakeOutOpts", func() {
var opts TakeOutOpts

It("has Args", func() {
Expect(getStructTagForName("Args", &opts)).To(Equal(`positional-args:"true" required:"true"`))
})

Describe("MirrorPrefix", func() {
It("contains desired values", func() {
Expect(getStructTagForName("MirrorPrefix", &opts)).To(Equal(
`long:"mirror-prefix" short:"m" description:"Mirror prefix" optional:"true" default:"file:"`,
))
})
})

It("has VarErrors", func() {
Expect(getStructTagForName("VarErrors", &opts)).To(Equal(
`long:"var-errs" description:"Expect all variables to be found, otherwise error"`,
))
})

It("has VarErrorsUnused", func() {
Expect(getStructTagForName("VarErrorsUnused", &opts)).To(Equal(
`long:"var-errs-unused" description:"Expect all variables to be used, otherwise error"`,
))
})

})

Describe("TakeOutArgs", func() {
var opts *TakeOutArgs

BeforeEach(func() {
opts = &TakeOutArgs{}
})

Describe("Name", func() {
It("contains desired values", func() {
Expect(getStructTagForName("Name", opts)).To(Equal(
`positional-arg-name:"NAME" description:"file name of ops file"`,
))
})
})

Describe("Manifest", func() {
It("contains desired values", func() {
Expect(getStructTagForName("Manifest", opts)).To(Equal(
`positional-arg-name:"PATH" description:"Path to a template for take_out"`,
))
})
})

})

Describe("UpdateCloudConfigOpts", func() {
var opts *UpdateCloudConfigOpts

Expand Down
77 changes: 77 additions & 0 deletions cmd/take_out.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package cmd

import (
. "github.com/cloudfoundry/bosh-cli/cmd/opts"
boshtpl "github.com/cloudfoundry/bosh-cli/director/template"
"github.com/cloudfoundry/bosh-cli/takeout"
boshui "github.com/cloudfoundry/bosh-cli/ui"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
"gopkg.in/yaml.v2"
"os"
)

type TakeOutCmd struct {
ui boshui.UI
to takeout.Utensils
}

func NewTakeOutCmd(ui boshui.UI, d takeout.Utensils) TakeOutCmd {
return TakeOutCmd{ui: ui, to: d}
}

func (c TakeOutCmd) Run(opts TakeOutOpts) error {
tpl := boshtpl.NewTemplate(opts.Args.Manifest.Bytes)

bytes, err := tpl.Evaluate(opts.VarFlags.AsVariables(), opts.OpsFlags.AsOp(), boshtpl.EvaluateOpts{})
if err != nil {
return bosherr.WrapErrorf(err, "Evaluating manifest")
}
if _, err := os.Stat(opts.Args.Name); os.IsExist(err) {
return bosherr.WrapErrorf(err, "Takeout op name exists")
}
deployment, err := c.to.ParseDeployment(bytes)

if err != nil {
return bosherr.WrapError(err, "Problem parsing deployment")
}
c.ui.PrintLinef("Processing releases for offline use")
var releaseChanges []takeout.OpEntry
for _, r := range deployment.Releases {
if r.URL == "" {
c.ui.PrintLinef("Release does not have a URL for take_out; Name: %s / %s", r.Name, r.Version)
return bosherr.WrapErrorf(nil, "Provide an opsfile that has a URL or removes this release") // TODO
} else {
o, err := c.to.TakeOutRelease(r, c.ui, opts.MirrorPrefix)
if err != nil {
return err
}
releaseChanges = append(releaseChanges, o)
}
}
for _, s := range deployment.Stemcells {
err := c.to.TakeOutStemcell(s, c.ui, opts.StemcellType)
if err != nil {

}
}

y, _ := yaml.Marshal(releaseChanges)
c.ui.PrintLinef("Writing take_out operation to file: " + opts.Args.Name)
takeoutOp, err := os.Create(opts.Args.Name)
if err != nil {
return err
}
if takeoutOp != nil {
defer func() {
if ferr := takeoutOp.Close(); ferr != nil {
err = ferr
}
}()
}
_, err = takeoutOp.WriteString("---\n")
_, err = takeoutOp.WriteString(string(y))
if err != nil {
return err
}
return nil
}
Loading

0 comments on commit 8e6a507

Please sign in to comment.