Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get cluster fixes #153

Merged
merged 3 commits into from
Aug 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions pkg/eks/eks.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (c *ClusterProvider) doListClusters(chunkSize int64, printer printers.Outpu
}
}

printer.PrintObj(allClusterNames, os.Stdout)
printer.PrintObj("clusters", allClusterNames, os.Stdout)

return nil
}
Expand All @@ -141,9 +141,11 @@ func (c *ClusterProvider) doGetCluster(clusterName *string, printer printers.Out
return errors.Wrapf(err, "unable to describe control plane %q", *clusterName)
}
logger.Debug("cluster = %#v", output)

clusters := []*awseks.Cluster{output.Cluster} // TODO: in the future this will have multiple clusters
printer.PrintObj("clusters", clusters, os.Stdout)

if *output.Cluster.Status == awseks.ClusterStatusActive {
clusters := []*awseks.Cluster{output.Cluster} // TODO: in the future this will have multiple clusters
printer.PrintObj(clusters, os.Stdout)

if logger.Level >= 4 {
stacks, err := c.ListReadyStacks(fmt.Sprintf("^EKS-%s-.*$", *clusterName))
Expand Down
90 changes: 77 additions & 13 deletions pkg/eks/eks_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package eks_test

import (
"bytes"
"fmt"
"time"
"io/ioutil"
"os"

"github.com/aws/aws-sdk-go/aws"
cfn "github.com/aws/aws-sdk-go/service/cloudformation"
Expand Down Expand Up @@ -31,12 +33,10 @@ var _ = Describe("Eks", func() {
var (
clusterName string
err error
created time.Time
)

BeforeEach(func() {
clusterName = "test-cluster"
created = time.Now()

p = testutils.NewMockProvider()

Expand All @@ -50,16 +50,7 @@ var _ = Describe("Eks", func() {
p.MockEKS().On("DescribeCluster", mock.MatchedBy(func(input *awseks.DescribeClusterInput) bool {
return *input.Name == clusterName
})).Return(&awseks.DescribeClusterOutput{
Cluster: &awseks.Cluster{
Name: aws.String(clusterName),
Status: aws.String(awseks.ClusterStatusActive),
Arn: aws.String("arn-12345678"),
CreatedAt: &created,
ResourcesVpcConfig: &awseks.VpcConfigResponse{
VpcId: aws.String("vpc-1234"),
SubnetIds: []*string{aws.String("sub1"), aws.String("sub2")},
},
},
Cluster: testutils.NewFakeCluster(clusterName, awseks.ClusterStatusActive),
}, nil)
})

Expand Down Expand Up @@ -117,6 +108,79 @@ var _ = Describe("Eks", func() {
})
})

Context("with a cluster name but cluster isn't ready", func() {
var (
clusterName string
err error
originalStdout *os.File
reader *os.File
writer *os.File
)

BeforeEach(func() {
originalStdout = os.Stdout
reader, writer, _ = os.Pipe()
os.Stdout = writer

clusterName = "test-cluster"
logger.Level = 1

p = testutils.NewMockProvider()

c = &ClusterProvider{
Spec: &ClusterConfig{
ClusterName: clusterName,
},
Provider: p,
}

p.MockEKS().On("DescribeCluster", mock.MatchedBy(func(input *awseks.DescribeClusterInput) bool {
return *input.Name == clusterName
})).Return(&awseks.DescribeClusterOutput{
Cluster: testutils.NewFakeCluster(clusterName, awseks.ClusterStatusDeleting),
}, nil)
})

JustBeforeEach(func() {
err = c.ListClusters(100, output)
})

AfterEach(func() {
os.Stdout = originalStdout
})

It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})

It("should have called AWS EKS service once", func() {
Expect(p.MockEKS().AssertNumberOfCalls(GinkgoT(), "DescribeCluster", 1)).To(BeTrue())
})

It("should not call AWS CFN ListStackPages", func() {
Expect(p.MockCloudFormation().AssertNumberOfCalls(GinkgoT(), "ListStacksPages", 0)).To(BeTrue())
})

It("the output should equal the golden file singlecluster_deleting.golden", func() {
writer.Close()
g, err := ioutil.ReadFile("testdata/singlecluster_deleting.golden")
if err != nil {
GinkgoT().Fatalf("failed reading .golden: %s", err)
}

actualOutput, _ := ioutil.ReadAll(reader)

bytesAreEqual := bytes.Equal(actualOutput, g)

if !bytesAreEqual {
fmt.Printf("\nActual:\n%s\n", string(actualOutput))
fmt.Printf("Expected:\n%s\n", string(g))
}

Expect(bytesAreEqual).To(BeTrue())
})
})

Context("with no cluster name", func() {
var (
err error
Expand Down
21 changes: 21 additions & 0 deletions pkg/eks/testdata/singlecluster_deleting.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[
{
"Arn": "arn-12345678",
"CertificateAuthority": null,
"ClientRequestToken": null,
"CreatedAt": "0001-01-01T00:00:00Z",
"Endpoint": null,
"Name": "test-cluster",
"ResourcesVpcConfig": {
"SecurityGroupIds": null,
"SubnetIds": [
"sub1",
"sub2"
],
"VpcId": "vpc-1234"
},
"RoleArn": null,
"Status": "DELETING",
"Version": null
}
]
2 changes: 1 addition & 1 deletion pkg/printers/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewJSONPrinter() OutputPrinter {

// PrintObj will print the passed object formatted as JSON to
// the supplied writer.
func (j *JSONPrinter) PrintObj(obj interface{}, writer io.Writer) error {
func (j *JSONPrinter) PrintObj(kind string, obj interface{}, writer io.Writer) error {
b, err := json.MarshalIndent(obj, j.prefix, j.indent)
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions pkg/printers/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var _ = Describe("JSON Printer", func() {

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj([]*awseks.Cluster{cluster}, w)
err = printer.PrintObj("clusters", []*awseks.Cluster{cluster}, w)
w.Flush()
})

Expand Down Expand Up @@ -121,7 +121,7 @@ var _ = Describe("JSON Printer", func() {

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj(clusters, w)
err = printer.PrintObj("clusters", clusters, w)
w.Flush()
})

Expand Down
6 changes: 5 additions & 1 deletion pkg/printers/printers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import (
"io"
)

// OutputPrinter is the interface that printer must implement. This allows
// new printers to be added in the future.
type OutputPrinter interface {
PrintObj(interface{}, io.Writer) error
PrintObj(kind string, obj interface{}, writer io.Writer) error
}

// NewPrinter creates a new printer based in the printer type requested
// as a string.
func NewPrinter(printerType string) (OutputPrinter, error) {
var printer OutputPrinter

Expand Down
20 changes: 19 additions & 1 deletion pkg/printers/table.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package printers

import (
"bufio"
"fmt"
"io"
"reflect"
"strings"

"github.com/pkg/errors"
"k8s.io/kops/util/pkg/tables"
)

Expand All @@ -20,10 +25,23 @@ func NewTablePrinter() OutputPrinter {

// PrintObj will print the passed object formatted as textual
// table to the supplied writer.
func (t *TablePrinter) PrintObj(obj interface{}, writer io.Writer) error {
func (t *TablePrinter) PrintObj(kind string, obj interface{}, writer io.Writer) error {
itemsValue := reflect.ValueOf(obj)
if itemsValue.Kind() != reflect.Slice {
return errors.Errorf("table printer expects a slice but the kind was %v", itemsValue.Kind())
}

if itemsValue.Len() == 0 {
w := bufio.NewWriter(writer)
w.WriteString(fmt.Sprintf("No %s found\n", strings.ToLower(kind)))
w.Flush()
return nil
}

return t.table.Render(obj, writer, t.columnames...)
}

// AddColumn adds a column to the table that will be printed
func (t *TablePrinter) AddColumn(name string, getter interface{}) {
t.columnames = append(t.columnames, name)
t.table.AddColumn(name, getter)
Expand Down
81 changes: 77 additions & 4 deletions pkg/printers/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var _ = Describe("Table Printer", func() {
_ = printer.(*TablePrinter)
})

Context("given a cluster struct and calling PrintObj", func() {
Context("given just a cluster struct (no slice) and calling PrintObj", func() {
var (
cluster *awseks.Cluster
err error
Expand All @@ -64,7 +64,80 @@ var _ = Describe("Table Printer", func() {

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj([]*awseks.Cluster{cluster}, w)
err = printer.PrintObj("clusters", cluster, w)
w.Flush()
})

AfterEach(func() {
actualBytes.Reset()
})

It("should have returned an error", func() {
Expect(err).To(HaveOccurred())
})
})

Context("given an empty slice with no cluster structs and calling PrintObj", func() {
var (
err error
actualBytes bytes.Buffer
)

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj("clusters", []*awseks.Cluster{}, w)
w.Flush()
})

AfterEach(func() {
actualBytes.Reset()
})

It("should not error", func() {
Expect(err).NotTo(HaveOccurred())
})

It("the output should equal the golden file tabletest_emptyslicegolden", func() {
g, err := ioutil.ReadFile("testdata/tabletest_emptyslice.golden")
if err != nil {
GinkgoT().Fatalf("failed reading .golden: %s", err)
}

bytesAreEqual := bytes.Equal(actualBytes.Bytes(), g)

if !bytesAreEqual {
fmt.Printf("\nActual:\n%s\n", string(actualBytes.Bytes()))
fmt.Printf("Expected:\n%s\n", string(g))
}

Expect(bytesAreEqual).To(BeTrue())
})
})

Context("given a slice with a cluster struct and calling PrintObj", func() {
var (
cluster *awseks.Cluster
err error
actualBytes bytes.Buffer
)

BeforeEach(func() {
created := &time.Time{}
cluster = &awseks.Cluster{
Name: aws.String("test-cluster"),
Status: aws.String(awseks.ClusterStatusActive),
Arn: aws.String("arn-12345678"),
CreatedAt: created,
ResourcesVpcConfig: &awseks.VpcConfigResponse{
VpcId: aws.String("vpc-1234"),
SubnetIds: []*string{aws.String("sub1"), aws.String("sub2")},
},
}
})

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj("clusters", []*awseks.Cluster{cluster}, w)
w.Flush()
})

Expand Down Expand Up @@ -93,7 +166,7 @@ var _ = Describe("Table Printer", func() {
})
})

Context("given 2 cluster structs and calling PrintObj", func() {
Context("given a slice with 2 cluster structs and calling PrintObj", func() {
var (
clusters []*awseks.Cluster
err error
Expand Down Expand Up @@ -128,7 +201,7 @@ var _ = Describe("Table Printer", func() {

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj(clusters, w)
err = printer.PrintObj("clusters", clusters, w)
w.Flush()
})

Expand Down
1 change: 1 addition & 0 deletions pkg/printers/testdata/tabletest_emptyslice.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
No clusters found
2 changes: 1 addition & 1 deletion pkg/printers/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func NewYAMLPrinter() OutputPrinter {

// PrintObj will print the passed object formatted as YAML to
// the supplied writer.
func (j *YAMLPrinter) PrintObj(obj interface{}, writer io.Writer) error {
func (j *YAMLPrinter) PrintObj(kind string, obj interface{}, writer io.Writer) error {
b, err := yaml.Marshal(obj)
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions pkg/printers/yaml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ var _ = Describe("YAML Printer", func() {

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj([]*awseks.Cluster{cluster}, w)
err = printer.PrintObj("clusters", []*awseks.Cluster{cluster}, w)
w.Flush()
})

Expand Down Expand Up @@ -124,7 +124,7 @@ var _ = Describe("YAML Printer", func() {

JustBeforeEach(func() {
w := bufio.NewWriter(&actualBytes)
err = printer.PrintObj(clusters, w)
err = printer.PrintObj("clusters", clusters, w)
w.Flush()
})

Expand Down
Loading