Merge pull request #9 from adamreese/get-deployments

feat(get): add get deployment command
pull/291/head
Adam Reese 9 years ago
commit 20d3ea9fb6

@ -0,0 +1,29 @@
package main
import (
"errors"
"github.com/codegangsta/cli"
"github.com/deis/helm-dm/format"
)
func getCmd() cli.Command {
return cli.Command{
Name: "get",
Usage: "Retrieves the supplied deployment",
Action: func(c *cli.Context) { run(c, get) },
}
}
func get(c *cli.Context) error {
args := c.Args()
if len(args) < 1 {
return errors.New("First argument, deployment name, is required. Try 'helm get --help'")
}
name := args[0]
deployment, err := client(c).GetDeployment(name)
if err != nil {
return err
}
return format.YAML(deployment)
}

@ -4,11 +4,11 @@ import (
"os"
"github.com/codegangsta/cli"
"github.com/deis/helm-dm/dm"
"github.com/deis/helm-dm/format"
)
var version = "0.0.1"
var isDebugging bool
func main() {
app := cli.NewApp()
@ -25,17 +25,16 @@ func main() {
EnvVar: "HELM_HOST",
Value: "https://localhost:8181/FIXME_NOT_RIGHT",
},
cli.IntFlag{
Name: "timeout",
Usage: "Time in seconds to wait for response",
Value: 10,
},
cli.BoolFlag{
Name: "debug",
Usage: "Enable verbose debugging output",
},
}
app.Before = func(ctx *cli.Context) error {
isDebugging = ctx.Bool("debug")
return nil
}
app.Run(os.Args)
}
@ -181,6 +180,7 @@ func commands() []cli.Command {
Name: "search",
},
listCmd(),
getCmd(),
}
}
@ -190,3 +190,10 @@ func run(c *cli.Context, f func(c *cli.Context) error) {
os.Exit(1)
}
}
func client(c *cli.Context) *dm.Client {
host := c.GlobalString("host")
debug := c.GlobalBool("debug")
timeout := c.GlobalInt("timeout")
return dm.NewClient(host).SetDebug(debug).SetTimeout(timeout)
}

@ -1,11 +1,7 @@
package main
import (
"fmt"
"os"
"github.com/codegangsta/cli"
"github.com/deis/helm-dm/dm"
"github.com/deis/helm-dm/format"
)
@ -13,21 +9,14 @@ func listCmd() cli.Command {
return cli.Command{
Name: "list",
Usage: "Lists the deployments in the cluster",
Action: func(c *cli.Context) {
if err := list(c.GlobalString("host")); err != nil {
format.Err("%s (Is the cluster running?)", err)
os.Exit(1)
}
},
Action: func(c *cli.Context) { run(c, list) },
}
}
func list(host string) error {
client := dm.NewClient(host).SetDebug(isDebugging)
list, err := client.ListDeployments()
func list(c *cli.Context) error {
list, err := client(c).ListDeployments()
if err != nil {
return err
}
fmt.Println(list)
return nil
return format.YAML(list)
}

@ -11,6 +11,8 @@ import (
"path/filepath"
"strings"
"time"
"github.com/kubernetes/deployment-manager/common"
)
// The default HTTP timeout
@ -67,6 +69,12 @@ func (c *Client) SetTransport(tr http.RoundTripper) *Client {
return c
}
// SetTimeout sets a timeout for http connections
func (c *Client) SetTimeout(seconds int) *Client {
c.HTTPTimeout = time.Duration(time.Duration(seconds) * time.Second)
return c
}
// url constructs the URL.
func (c *Client) url(rawurl string) (string, error) {
u, err := url.Parse(rawurl)
@ -98,6 +106,9 @@ func (c *Client) CallService(path, method, action string, dest interface{}, read
// callHTTP is a low-level primative for executing HTTP operations.
func (c *Client) callHTTP(path, method, action string, reader io.ReadCloser) (string, error) {
request, err := http.NewRequest(method, path, reader)
// TODO: dynamically set version
request.Header.Set("User-Agent", "helm/0.0.1")
request.Header.Add("Content-Type", "application/json")
client := http.Client{
@ -125,10 +136,34 @@ func (c *Client) callHTTP(path, method, action string, reader io.ReadCloser) (st
return string(body), nil
}
// DefaultServerURL converts a host, host:port, or URL string to the default base server API path
// to use with a Client
func DefaultServerURL(host string) (*url.URL, error) {
if host == "" {
return nil, fmt.Errorf("host must be a URL or a host:port pair")
}
base := host
hostURL, err := url.Parse(base)
if err != nil {
return nil, err
}
if hostURL.Scheme == "" {
hostURL, err = url.Parse(DefaultHTTPProtocol + "://" + base)
if err != nil {
return nil, err
}
}
if len(hostURL.Path) > 0 && !strings.HasSuffix(hostURL.Path, "/") {
hostURL.Path = hostURL.Path + "/"
}
return hostURL, nil
}
// ListDeployments lists the deployments in DM.
func (c *Client) ListDeployments() ([]string, error) {
var l []string
if err := c.CallService("deployments", "GET", "foo", &l, nil); err != nil {
if err := c.CallService("deployments", "GET", "list deployments", &l, nil); err != nil {
return nil, err
}
@ -181,26 +216,11 @@ func (c *Client) DeployChart(filename, deployname string) error {
return nil
}
// DefaultServerURL converts a host, host:port, or URL string to the default base server API path
// to use with a Client
func DefaultServerURL(host string) (*url.URL, error) {
if host == "" {
return nil, fmt.Errorf("host must be a URL or a host:port pair")
}
base := host
hostURL, err := url.Parse(base)
if err != nil {
return nil, err
}
if hostURL.Scheme == "" {
hostURL, err = url.Parse(DefaultHTTPProtocol + "://" + base)
if err != nil {
// GetDeployment retrieves the supplied deployment
func (c *Client) GetDeployment(name string) (*common.Deployment, error) {
var deployment *common.Deployment
if err := c.CallService(filepath.Join("deployments", name), "GET", "get deployment", &deployment, nil); err != nil {
return nil, err
}
}
if len(hostURL.Path) > 0 && !strings.HasSuffix(hostURL.Path, "/") {
hostURL.Path = hostURL.Path + "/"
}
return hostURL, nil
return deployment, nil
}

@ -3,7 +3,10 @@ package dm
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/kubernetes/deployment-manager/common"
)
func TestDefaultServerURL(t *testing.T) {
@ -65,13 +68,9 @@ type fakeClient struct {
*Client
server *httptest.Server
handler http.HandlerFunc
response []byte
}
func (c *fakeClient) setup() *fakeClient {
c.handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(c.response)
})
c.server = httptest.NewServer(c.handler)
c.Client = NewClient(c.server.URL)
return c
@ -81,9 +80,22 @@ func (c *fakeClient) teardown() {
c.server.Close()
}
func TestUserAgent(t *testing.T) {
fc := &fakeClient{
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.UserAgent(), "helm") {
t.Error("user agent is not set")
}
}),
}
fc.setup().ListDeployments()
}
func TestListDeployments(t *testing.T) {
fc := &fakeClient{
response: []byte(`["guestbook.yaml"]`),
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`["guestbook.yaml"]`))
}),
}
defer fc.teardown()
@ -96,3 +108,25 @@ func TestListDeployments(t *testing.T) {
t.Fatal("expected a single deployment")
}
}
func TestGetDeployment(t *testing.T) {
fc := &fakeClient{
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`{"name":"guestbook.yaml","id":0,"createdAt":"2016-02-08T12:17:49.251658308-08:00","deployedAt":"2016-02-08T12:17:49.251658589-08:00","modifiedAt":"2016-02-08T12:17:51.177518098-08:00","deletedAt":"0001-01-01T00:00:00Z","state":{"status":"Deployed"},"latestManifest":"manifest-1454962670728402229"}`))
}),
}
defer fc.teardown()
d, err := fc.setup().GetDeployment("guestbook.yaml")
if err != nil {
t.Fatal(err)
}
if d.Name != "guestbook.yaml" {
t.Fatalf("expected deployment name 'guestbook.yaml', got '%s'", d.Name)
}
if d.State.Status != common.DeployedStatus {
t.Fatalf("expected deployment status 'Deployed', got '%s'", d.State.Status)
}
}

@ -3,6 +3,8 @@ package format
import (
"fmt"
"os"
"github.com/ghodss/yaml"
)
// This is all just placeholder.
@ -35,3 +37,13 @@ func Warning(msg string, v ...interface{}) {
msg = "[Warning] " + msg + "\n"
fmt.Fprintf(os.Stdout, msg, v...)
}
func YAML(v interface{}) error {
y, err := yaml.Marshal(v)
if err != nil {
return fmt.Errorf("Failed to serialize to yaml: %s", v.(string))
}
Msg(string(y))
return nil
}

Loading…
Cancel
Save