Skip to content

Commit

Permalink
Implement cpi-config and update-cpi-config commands
Browse files Browse the repository at this point in the history
  • Loading branch information
dpb587-pivotal authored and Ming Xiao committed Nov 11, 2016
1 parent 56c2abe commit 49a28f8
Show file tree
Hide file tree
Showing 12 changed files with 507 additions and 2 deletions.
6 changes: 6 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ func (c Cmd) Execute() (cmdErr error) {
case *UpdateCloudConfigOpts:
return NewUpdateCloudConfigCmd(deps.UI, c.director()).Run(*opts)

case *CPIConfigOpts:
return NewCPIConfigCmd(deps.UI, c.director()).Run()

case *UpdateCPIConfigOpts:
return NewUpdateCPIConfigCmd(deps.UI, c.director()).Run(*opts)

case *RuntimeConfigOpts:
return NewRuntimeConfigCmd(deps.UI, c.director()).Run()

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

import (
boshdir "github.com/cloudfoundry/bosh-cli/director"
boshui "github.com/cloudfoundry/bosh-cli/ui"
)

type CPIConfigCmd struct {
ui boshui.UI
director boshdir.Director
}

func NewCPIConfigCmd(ui boshui.UI, director boshdir.Director) CPIConfigCmd {
return CPIConfigCmd{ui: ui, director: director}
}

func (c CPIConfigCmd) Run() error {
cpiConfig, err := c.director.LatestCPIConfig()
if err != nil {
return err
}

c.ui.PrintBlock(cpiConfig.Properties)

return nil
}
52 changes: 52 additions & 0 deletions cmd/cpi_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd_test

import (
"errors"

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

. "github.com/cloudfoundry/bosh-cli/cmd"
boshdir "github.com/cloudfoundry/bosh-cli/director"
fakedir "github.com/cloudfoundry/bosh-cli/director/directorfakes"
fakeui "github.com/cloudfoundry/bosh-cli/ui/fakes"
)

var _ = Describe("CPIConfigCmd", func() {
var (
ui *fakeui.FakeUI
director *fakedir.FakeDirector
command CPIConfigCmd
)

BeforeEach(func() {
ui = &fakeui.FakeUI{}
director = &fakedir.FakeDirector{}
command = NewCPIConfigCmd(ui, director)
})

Describe("Run", func() {
act := func() error { return command.Run() }

It("shows cpi config", func() {
cpiConfig := boshdir.CPIConfig{
Properties: "some-properties",
}

director.LatestCPIConfigReturns(cpiConfig, nil)

err := act()
Expect(err).ToNot(HaveOccurred())

Expect(ui.Blocks).To(Equal([]string{"some-properties"}))
})

It("returns error if cpi config cannot be retrieved", func() {
director.LatestCPIConfigReturns(boshdir.CPIConfig{}, errors.New("fake-err"))

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})
})
})
4 changes: 2 additions & 2 deletions cmd/deployments_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (t DeploymentsTable) Print() error {
return err
}

config, err := d.CloudConfig()
cloud_config, err := d.CloudConfig()
if err != nil {
return err
}
Expand All @@ -42,7 +42,7 @@ func (t DeploymentsTable) Print() error {
boshtbl.NewValueString(d.Name()),
boshtbl.NewValueStrings(t.takeReleases(releases)),
boshtbl.NewValueStrings(t.takeStemcells(stemcells)),
boshtbl.NewValueString(config),
boshtbl.NewValueString(cloud_config),
})
}

Expand Down
19 changes: 19 additions & 0 deletions cmd/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ type BoshOpts struct {
CloudConfig CloudConfigOpts `command:"cloud-config" alias:"cc" description:"Show current cloud config"`
UpdateCloudConfig UpdateCloudConfigOpts `command:"update-cloud-config" alias:"ucc" description:"Update current cloud config"`

// CPI Config
CPIConfig CPIConfigOpts `command:"cpi-config" description:"Show current CPI config"`
UpdateCPIConfig UpdateCPIConfigOpts `command:"update-cpi-config" description:"Update current CPI config"`

// Runtime config
RuntimeConfig RuntimeConfigOpts `command:"runtime-config" alias:"rc" description:"Show current runtime config"`
UpdateRuntimeConfig UpdateRuntimeConfigOpts `command:"update-runtime-config" alias:"urc" description:"Update current runtime config"`
Expand Down Expand Up @@ -294,6 +298,21 @@ type UpdateCloudConfigArgs struct {
CloudConfig FileBytesArg `positional-arg-name:"PATH" description:"Path to a cloud config file"`
}

type CPIConfigOpts struct {
cmd
}

type UpdateCPIConfigOpts struct {
Args UpdateCPIConfigArgs `positional-args:"true" required:"true"`
VarFlags
OpsFlags
cmd
}

type UpdateCPIConfigArgs struct {
CPIConfig FileBytesArg `positional-arg-name:"PATH" description:"Path to a CPI config file"`
}

// Runtime config
type RuntimeConfigOpts struct {
cmd
Expand Down
16 changes: 16 additions & 0 deletions cmd/opts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,22 @@ var _ = Describe("Opts", func() {
})
})

Describe("CPIConfig", func() {
It("contains desired values", func() {
Expect(getStructTagForName("CPIConfig", opts)).To(Equal(
`command:"cpi-config" description:"Show current CPI config"`,
))
})
})

Describe("UpdateCPIConfig", func() {
It("contains desired values", func() {
Expect(getStructTagForName("UpdateCPIConfig", opts)).To(Equal(
`command:"update-cpi-config" description:"Update current CPI config"`,
))
})
})

Describe("RuntimeConfig", func() {
It("contains desired values", func() {
Expect(getStructTagForName("RuntimeConfig", opts)).To(Equal(
Expand Down
34 changes: 34 additions & 0 deletions cmd/update_cpi_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cmd

import (
bosherr "github.com/cloudfoundry/bosh-utils/errors"

boshdir "github.com/cloudfoundry/bosh-cli/director"
boshtpl "github.com/cloudfoundry/bosh-cli/director/template"
boshui "github.com/cloudfoundry/bosh-cli/ui"
)

type UpdateCPIConfigCmd struct {
ui boshui.UI
director boshdir.Director
}

func NewUpdateCPIConfigCmd(ui boshui.UI, director boshdir.Director) UpdateCPIConfigCmd {
return UpdateCPIConfigCmd{ui: ui, director: director}
}

func (c UpdateCPIConfigCmd) Run(opts UpdateCPIConfigOpts) error {
tpl := boshtpl.NewTemplate(opts.Args.CPIConfig.Bytes)

bytes, err := tpl.Evaluate(opts.VarFlags.AsVariables(), opts.OpsFlags.AsOps(), boshtpl.EvaluateOpts{})
if err != nil {
return bosherr.WrapErrorf(err, "Evaluating cpi config")
}

err = c.ui.AskForConfirmation()
if err != nil {
return err
}

return c.director.UpdateCPIConfig(bytes)
}
103 changes: 103 additions & 0 deletions cmd/update_cpi_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package cmd_test

import (
"errors"

"github.com/cppforlife/go-patch/patch"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

. "github.com/cloudfoundry/bosh-cli/cmd"
fakedir "github.com/cloudfoundry/bosh-cli/director/directorfakes"
boshtpl "github.com/cloudfoundry/bosh-cli/director/template"
fakeui "github.com/cloudfoundry/bosh-cli/ui/fakes"
)

var _ = Describe("UpdateCPIConfigCmd", func() {
var (
ui *fakeui.FakeUI
director *fakedir.FakeDirector
command UpdateCPIConfigCmd
)

BeforeEach(func() {
ui = &fakeui.FakeUI{}
director = &fakedir.FakeDirector{}
command = NewUpdateCPIConfigCmd(ui, director)
})

Describe("Run", func() {
var (
opts UpdateCPIConfigOpts
)

BeforeEach(func() {
opts = UpdateCPIConfigOpts{
Args: UpdateCPIConfigArgs{
CPIConfig: FileBytesArg{Bytes: []byte("cpi-config")},
},
}
})

act := func() error { return command.Run(opts) }

It("updates cpi config", func() {
err := act()
Expect(err).ToNot(HaveOccurred())

Expect(director.UpdateCPIConfigCallCount()).To(Equal(1))

bytes := director.UpdateCPIConfigArgsForCall(0)
Expect(bytes).To(Equal([]byte("cpi-config\n")))
})

It("updates templated cpi config", func() {
opts.Args.CPIConfig = FileBytesArg{
Bytes: []byte("name: ((name))\ntype: ((type))"),
}

opts.VarKVs = []boshtpl.VarKV{
{Name: "name", Value: "val1-from-kv"},
}

opts.VarsFiles = []boshtpl.VarsFileArg{
{Vars: boshtpl.Variables(map[string]interface{}{"name": "val1-from-file"})},
{Vars: boshtpl.Variables(map[string]interface{}{"type": "val2-from-file"})},
}

opts.OpsFiles = []OpsFileArg{
{
Ops: patch.Ops([]patch.Op{
patch.ReplaceOp{Path: patch.MustNewPointerFromString("/xyz?"), Value: "val"},
}),
},
}

err := act()
Expect(err).ToNot(HaveOccurred())

Expect(director.UpdateCPIConfigCallCount()).To(Equal(1))

bytes := director.UpdateCPIConfigArgsForCall(0)
Expect(bytes).To(Equal([]byte("name: val1-from-kv\ntype: val2-from-file\nxyz: val\n")))
})

It("does not stop if confirmation is rejected", func() {
ui.AskedConfirmationErr = errors.New("stop")

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("stop"))

Expect(director.UpdateCPIConfigCallCount()).To(Equal(0))
})

It("returns error if updating failed", func() {
director.UpdateCPIConfigReturns(errors.New("fake-err"))

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})
})
})
54 changes: 54 additions & 0 deletions director/cpi_configs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package director

import (
"net/http"

bosherr "github.com/cloudfoundry/bosh-utils/errors"
)

type CPIConfig struct {
Properties string
}

func (d DirectorImpl) LatestCPIConfig() (CPIConfig, error) {
resps, err := d.client.CPIConfigs()
if err != nil {
return CPIConfig{}, err
}

if len(resps) == 0 {
return CPIConfig{}, bosherr.Error("No CPI config")
}

return resps[0], nil
}

func (d DirectorImpl) UpdateCPIConfig(manifest []byte) error {
return d.client.UpdateCPIConfig(manifest)
}

func (c Client) CPIConfigs() ([]CPIConfig, error) {
var resps []CPIConfig

err := c.clientRequest.Get("/cpi_configs?limit=1", &resps)
if err != nil {
return resps, bosherr.WrapErrorf(err, "Finding CPI configs")
}

return resps, nil
}

func (c Client) UpdateCPIConfig(manifest []byte) error {
path := "/cpi_configs"

setHeaders := func(req *http.Request) {
req.Header.Add("Content-Type", "text/yaml")
}

_, _, err := c.clientRequest.RawPost(path, manifest, setHeaders)
if err != nil {
return bosherr.WrapErrorf(err, "Updating CPI config")
}

return nil
}
Loading

0 comments on commit 49a28f8

Please sign in to comment.