Commit 9e1dbeaa authored by Matt Butcher's avatar Matt Butcher

feat(*): stub out install

parent d3dfdc29
......@@ -22,6 +22,9 @@ func commands() []cli.Command {
return []cli.Command{
{
Name: "install",
Usage: "Initialize the client and install DM on Kubernetes.",
Description: ``,
Action: func(c *cli.Context) { install() },
},
{
Name: "target",
......
package main
import (
"github.com/deis/helm-dm/dm"
"github.com/deis/helm-dm/format"
"github.com/deis/helm-dm/kubectl"
)
func install() error {
runner := &kubectl.PrintRunner{}
out, err := dm.Install(runner)
if err != nil {
format.Error("Error installing: %s %s", out, err)
}
format.Msg(out)
return nil
}
package dm
import (
"github.com/deis/helm-dm/kubectl"
)
// Install uses kubectl to install the base DM.
//
// Returns the string output received from the operation, and an error if the
// command failed.
func Install(runner kubectl.Runner) (string, error) {
o, err := runner.Create([]byte(InstallYAML), "dm")
return string(o), err
}
// InstallYAML is the installation YAML for DM.
const InstallYAML = `
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
######################################################################
---
apiVersion: v1
kind: Namespace
metadata:
labels:
app: dm
name: dm-namespace
name: dm
---
apiVersion: v1
kind: Service
metadata:
labels:
app: dm
name: expandybird-service
name: expandybird-service
namespace: dm
spec:
ports:
- name: expandybird
port: 8081
targetPort: 8080
selector:
app: dm
name: expandybird
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: dm
name: expandybird-rc
name: expandybird-rc
namespace: dm
spec:
replicas: 2
selector:
app: dm
name: expandybird
template:
metadata:
labels:
app: dm
name: expandybird
spec:
containers:
- env: []
image: gcr.io/dm-k8s-testing/expandybird:latest
name: expandybird
ports:
- containerPort: 8080
name: expandybird
---
apiVersion: v1
kind: Service
metadata:
labels:
app: dm
name: resourcifier-service
name: resourcifier-service
namespace: dm
spec:
ports:
- name: resourcifier
port: 8082
targetPort: 8080
selector:
app: dm
name: resourcifier
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: dm
name: resourcifier-rc
name: resourcifier-rc
namespace: dm
spec:
replicas: 2
selector:
app: dm
name: resourcifier
template:
metadata:
labels:
app: dm
name: resourcifier
spec:
containers:
- env: []
image: gcr.io/dm-k8s-testing/resourcifier:latest
name: resourcifier
ports:
- containerPort: 8080
name: resourcifier
---
apiVersion: v1
kind: Service
metadata:
labels:
app: dm
name: manager-service
name: manager-service
namespace: dm
spec:
ports:
- name: manager
port: 8080
targetPort: 8080
selector:
app: dm
name: manager
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: dm
name: manager-rc
name: manager-rc
namespace: dm
spec:
replicas: 1
selector:
app: dm
name: manager
template:
metadata:
labels:
app: dm
name: manager
spec:
containers:
- env: []
image: gcr.io/dm-k8s-testing/manager:latest
name: manager
ports:
- containerPort: 8080
name: manager
`
package format
import (
"fmt"
"os"
)
// This is all just placeholder.
func Error(msg string, v ...interface{}) {
msg = "[ERROR]" + msg + "\n"
fmt.Fprintf(os.Stderr, msg, v...)
}
func Info(msg string, v ...interface{}) {
msg = "[INFO]" + msg + "\n"
fmt.Fprintf(os.Stdout, msg, v...)
}
func Msg(msg string, v ...interface{}) {
fmt.Fprintf(os.Stdout, msg, v...)
}
package: github.com/engineyard/helm-dm
package: github.com/deis/helm-dm
import:
- package: github.com/codegangsta/cli
- package: github.com/kubernetes/deployment-manager
......
package kubectl
// ClusterInfo returns Kubernetes cluster info
func (r RealRunner) ClusterInfo() ([]byte, error) {
return command("cluster-info").CombinedOutput()
}
// ClusterInfo returns the commands to kubectl
func (r PrintRunner) ClusterInfo() ([]byte, error) {
cmd := command("cluster-info")
return []byte(cmd.String()), nil
}
package kubectl
import (
"bytes"
"fmt"
"io/ioutil"
"os/exec"
"strings"
)
type cmd struct {
*exec.Cmd
}
func command(args ...string) *cmd {
return &cmd{exec.Command(Path, args...)}
}
func assignStdin(cmd *cmd, in []byte) {
cmd.Stdin = bytes.NewBuffer(in)
}
func (c *cmd) String() string {
var stdin string
if c.Stdin != nil {
b, _ := ioutil.ReadAll(c.Stdin)
stdin = fmt.Sprintf("< %s", string(b))
}
return fmt.Sprintf("[CMD] %s %s", strings.Join(c.Args, " "), stdin)
}
package kubectl
// Create uploads a chart to Kubernetes
func (r RealRunner) Create(stdin []byte, ns string) ([]byte, error) {
args := []string{"create", "-f", "-"}
if ns != "" {
args = append([]string{"--namespace=" + ns}, args...)
}
cmd := command(args...)
assignStdin(cmd, stdin)
return cmd.CombinedOutput()
}
// Create returns the commands to kubectl
func (r PrintRunner) Create(stdin []byte, ns string) ([]byte, error) {
args := []string{"create", "-f", "-"}
if ns != "" {
args = append([]string{"--namespace=" + ns}, args...)
}
cmd := command(args...)
assignStdin(cmd, stdin)
return []byte(cmd.String()), nil
}
package kubectl
import (
"testing"
)
func TestPrintCreate(t *testing.T) {
var client Runner = PrintRunner{}
expected := `[CMD] kubectl --namespace=default-namespace create -f - < some stdin data`
out, err := client.Create([]byte("some stdin data"), "default-namespace")
if err != nil {
t.Error(err)
}
actual := string(out)
if expected != actual {
t.Fatalf("actual %s != expected %s", actual, expected)
}
}
package kubectl
// Delete removes a chart from Kubernetes.
func (r RealRunner) Delete(name, ktype, ns string) ([]byte, error) {
args := []string{"delete", ktype, name}
if ns != "" {
args = append([]string{"--namespace=" + ns}, args...)
}
return command(args...).CombinedOutput()
}
// Delete returns the commands to kubectl
func (r PrintRunner) Delete(name, ktype, ns string) ([]byte, error) {
args := []string{"delete", ktype, name}
if ns != "" {
args = append([]string{"--namespace=" + ns}, args...)
}
cmd := command(args...)
return []byte(cmd.String()), nil
}
package kubectl
// Get returns Kubernetes resources
func (r RealRunner) Get(stdin []byte, ns string) ([]byte, error) {
args := []string{"get", "-f", "-"}
if ns != "" {
args = append([]string{"--namespace=" + ns}, args...)
}
cmd := command(args...)
assignStdin(cmd, stdin)
return cmd.CombinedOutput()
}
// Get returns the commands to kubectl
func (r PrintRunner) Get(stdin []byte, ns string) ([]byte, error) {
args := []string{"get", "-f", "-"}
if ns != "" {
args = append([]string{"--namespace=" + ns}, args...)
}
cmd := command(args...)
assignStdin(cmd, stdin)
return []byte(cmd.String()), nil
}
package kubectl
import (
"testing"
)
func TestGet(t *testing.T) {
Client = TestRunner{
out: []byte("running the get command"),
}
expects := "running the get command"
out, _ := Client.Get([]byte{}, "")
if string(out) != expects {
t.Errorf("%s != %s", string(out), expects)
}
}
package kubectl
// Path is the path of the kubectl binary
var Path = "kubectl"
// Runner is an interface to wrap kubectl convenience methods
type Runner interface {
// ClusterInfo returns Kubernetes cluster info
ClusterInfo() ([]byte, error)
// Create uploads a chart to Kubernetes
Create([]byte, string) ([]byte, error)
// Delete removes a chart from Kubernetes.
Delete(string, string, string) ([]byte, error)
// Get returns Kubernetes resources
Get([]byte, string) ([]byte, error)
}
// RealRunner implements Runner to execute kubectl commands
type RealRunner struct{}
// PrintRunner implements Runner to return a []byte of the command to be executed
type PrintRunner struct{}
// Client stores the instance of Runner
var Client Runner = RealRunner{}
package kubectl
type TestRunner struct {
Runner
out []byte
err error
}
func (r TestRunner) Get(stdin []byte, ns string) ([]byte, error) {
return r.out, r.err
}
Markdown is supported
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