Commit 20d3ea9f authored by Adam Reese's avatar Adam Reese
Browse files

Merge pull request #9 from adamreese/get-deployments

feat(get): add get deployment command
parents fccfcc8e 6058cad0
main Release add-codeql dependabot/go_modules/github.com/docker/distribution-2.8.2incompatible dependabot/go_modules/github.com/lib/pq-1.10.9 dependabot/go_modules/github.com/rubenv/sql-migrate-1.4.0 dependabot/go_modules/golang.org/x/crypto-0.9.0 dependabot/go_modules/golang.org/x/term-0.8.0 dependabot/go_modules/k8s.io/klog/v2-2.100.1 dev-v2 feat-v3/event-emitter-lua kube-update-test release-2.0 release-2.1 release-2.10 release-2.11 release-2.12 release-2.13 release-2.14 release-2.15 release-2.16 release-2.17 release-2.2 release-2.3 release-2.4 release-2.5 release-2.6 release-2.7 release-2.8 release-2.9 release-3.0 release-3.1 release-3.10 release-3.11 release-3.12 release-3.2 release-3.3 release-3.4 release-3.5 release-3.6 release-3.6.1 release-3.6.2 release-3.7 release-3.8 release-3.9 release-v3.0.0-beta.4 1.999.0 v3.12.0 v3.12.0-rc.1 v3.12.0-dev.1 v3.11.3 v3.11.2 v3.11.1 v3.11.0 v3.11.0-rc.2 v3.11.0-rc.1 v3.10.3 v3.10.2 v3.10.1 v3.10.0 v3.10.0-rc.1 v3.9.4 v3.9.3 v3.9.2 v3.9.1 v3.9.0 v3.9.0-rc.1 v3.8.2 v3.8.1 v3.8.0 v3.8.0-rc.2 v3.8.0-rc.1 v3.7.2 v3.7.1 v3.7.0 v3.7.0-rc.3 v3.7.0-rc.2 v3.7.0-rc.1 v3.6.3 v3.6.2 v3.6.1 v3.6.0 v3.6.0-rc.1 v3.5.4 v3.5.3 v3.5.2 v3.5.1 v3.5.0 v3.5.0-rc.2 v3.5.0-rc.1 v3.4.2 v3.4.1 v3.4.0 v3.4.0-rc.1 v3.3.4 v3.3.3 v3.3.2 v3.3.1 v3.3.0 v3.3.0-rc.2 v3.3.0-rc.1 v3.2.4 v3.2.3 v3.2.2 v3.2.1 v3.2.0 v3.2.0-rc.1 v3.1.3 v3.1.2 v3.1.1 v3.1.0 v3.1.0-rc.3 v3.1.0-rc.2 v3.1.0-rc.1 v3.0.3 v3.0.2 v3.0.1 v3.0.0 v3.0.0-rc.4 v3.0.0-rc.3 v3.0.0-rc.2 v3.0.0-rc.1 v3.0.0-beta.5 v3.0.0-beta.4 v3.0.0-beta.3 v3.0.0-beta.2 v3.0.0-beta.1 v3.0.0-alpha.2 v3.0.0-alpha.1 v2.17.0 v2.17.0-rc.1 v2.16.12 v2.16.11 v2.16.10 v2.16.9 v2.16.8 v2.16.7 v2.16.6 v2.16.5 v2.16.4 v2.16.3 v2.16.2 v2.16.1 v2.16.0 v2.16.0-rc.2 v2.16.0-rc.1 v2.15.2 v2.15.1 v2.15.0 v2.15.0-rc.2 v2.15.0-rc.1 v2.14.3 v2.14.2 v2.14.1 v2.14.0 v2.14.0-rc.2 v2.14.0-rc.1 v2.13.1 v2.13.1-rc.1 v2.13.0 v2.13.0-rc.2 v2.13.0-rc.1 v2.12.3 v2.12.2 v2.12.1 v2.12.0 v2.12.0-rc.2 v2.12.0-rc.1 v2.11.0 v2.11.0-rc.4 v2.11.0-rc.3 v2.11.0-rc.2 v2.11.0-rc.1 v2.10.0 v2.10.0-rc.3 v2.10.0-rc.2 v2.10.0-rc.1 v2.9.1 v2.9.0 v2.9.0-rc5 v2.9.0-rc4 v2.9.0-rc3 v2.9.0-rc2 v2.9.0-rc1 v2.8.2 v2.8.2-rc1 v2.8.1 v2.8.0 v2.8.0-rc.1 v2.7.2 v2.7.1 v2.7.0 v2.7.0-rc1 v2.6.2 v2.6.1 v2.6.0 v2.5.1 v2.5.0 v2.4.2 v2.4.1 v2.4.0 v2.3.1 v2.3.0 v2.2.3 v2.2.2 v2.2.1 v2.2.0 v2.1.3 v2.1.2 v2.1.1 v2.1.0 v2.0.2 v2.0.1 v2.0.0 v2.0.0-rc.2 v2.0.0-rc.1 v2.0.0-beta.2 v2.0.0-beta.1 v2.0.0-alpha.5 v2.0.0-alpha.4 v2.0.0-alpha.3 v2.0.0-alpha.2 v2.0.0-alpha.1
No related merge requests found
Showing with 143 additions and 52 deletions
+143 -52
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)
}
package main
import (
"fmt"
"os"
"github.com/codegangsta/cli"
"github.com/deis/helm-dm/dm"
"github.com/deis/helm-dm/format"
)
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)
}
},
Name: "list",
Usage: "Lists the deployments in the cluster",
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 {
// 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 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
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) {
......@@ -63,15 +66,11 @@ func TestURL(t *testing.T) {
type fakeClient struct {
*Client
server *httptest.Server
handler http.HandlerFunc
response []byte
server *httptest.Server
handler http.HandlerFunc
}
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
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment