Skip to content

Commit

Permalink
deployment: Add list command (#30)
Browse files Browse the repository at this point in the history
Adds the deployment list command and an associated text template.

Signed-off-by: Marc Lopez <marc5.12@outlook.com>
  • Loading branch information
marclop committed Nov 11, 2019
1 parent df2d729 commit a01959c
Show file tree
Hide file tree
Showing 10 changed files with 416 additions and 0 deletions.
45 changes: 45 additions & 0 deletions cmd/deployment/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you 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.

package cmddeployment

import (
"github.com/spf13/cobra"

"github.com/elastic/ecctl/pkg/deployment"
"github.com/elastic/ecctl/pkg/ecctl"
)

var listCmd = &cobra.Command{
Use: "list",
Short: "Lists the platform's deployments",
PreRunE: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
res, err := deployment.List(deployment.ListParams{
API: ecctl.Get().API,
})
if err != nil {
return err
}

return ecctl.Get().Formatter.Format("deployment/list", res)
},
}

func init() {
Command.AddCommand(listCmd)
}
1 change: 1 addition & 0 deletions docs/ecctl_deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ ecctl deployment [flags]
* [ecctl deployment apm](ecctl_deployment_apm.md) - Manages APM deployments
* [ecctl deployment elasticsearch](ecctl_deployment_elasticsearch.md) - Manages Elasticsearch clusters
* [ecctl deployment kibana](ecctl_deployment_kibana.md) - Manages Kibana clusters
* [ecctl deployment list](ecctl_deployment_list.md) - Lists the platform's deployments
* [ecctl deployment note](ecctl_deployment_note.md) - Manages a deployment's notes
* [ecctl deployment show](ecctl_deployment_show.md) - Shows the specified deployment resources

43 changes: 43 additions & 0 deletions docs/ecctl_deployment_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## ecctl deployment list

Lists the platform's deployments

### Synopsis

Lists the platform's deployments

```
ecctl deployment list [flags]
```

### Options

```
-h, --help help for list
```

### Options inherited from parent commands

```
--apikey string API key to use to authenticate (If empty will look for EC_APIKEY environment variable)
--config string Config name, used to have multiple configs in $HOME/.ecctl/<env> (default "config")
--force Do not ask for confirmation
--format string Formats the output using a Go template
--host string Base URL to use (default "https://api.elastic-cloud.com")
--insecure Skips all TLS validation
--message string A message to set on cluster operation
--output string Output format [text|json] (default "text")
--pass string Password to use to authenticate (If empty will look for EC_PASS environment variable)
--pprof Enables pprofing and saves the profile to pprof-20060102150405
-q, --quiet Suppresses the configuration file used for the run, if any
--region string Elastic Cloud region
--timeout duration Timeout to use on all HTTP calls (default 30s)
--trace Enables tracing saves the trace to trace-20060102150405
--user string Username to use to authenticate (If empty will look for EC_USER environment variable)
--verbose Enable verbose mode
```

### SEE ALSO

* [ecctl deployment](ecctl_deployment.md) - Manages deployments

57 changes: 57 additions & 0 deletions pkg/deployment/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you 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.

package deployment

import (
"github.com/elastic/cloud-sdk-go/pkg/api"
"github.com/elastic/cloud-sdk-go/pkg/client/deployments"
"github.com/elastic/cloud-sdk-go/pkg/models"

"github.com/elastic/ecctl/pkg/util"
)

// ListParams is consumed by List.
type ListParams struct {
*api.API
}

// Validate ensures the parameters are usable.
func (params ListParams) Validate() error {
if params.API == nil {
return util.ErrAPIReq
}

return nil
}

// List returns the platform deployemnts
func List(params ListParams) (*models.DeploymentsListResponse, error) {
if err := params.Validate(); err != nil {
return nil, err
}

res, err := params.V1API.Deployments.ListDeployments(
deployments.NewListDeploymentsParams(),
params.AuthWriter,
)
if err != nil {
return nil, api.UnwrapError(err)
}

return res.Payload, nil
}
173 changes: 173 additions & 0 deletions pkg/deployment/list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you 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.

package deployment

import (
"errors"
"reflect"
"testing"

"github.com/elastic/cloud-sdk-go/pkg/api"
"github.com/elastic/cloud-sdk-go/pkg/api/mock"
"github.com/elastic/cloud-sdk-go/pkg/models"
"github.com/elastic/cloud-sdk-go/pkg/util/ec"

"github.com/elastic/ecctl/pkg/util"
)

var deploymentList = `{
"deployments": [
{
"id": "709551ecd21143adbb7a37bbf36c4321",
"name": "admin-console-elasticsearch",
"resources": [
{
"cloud_id": "admin-console-elasticsearch:MTkyLjE2OC40NC4xMC5pcC5lcy5pbzo5MjQzJDcwOTU1MWVjZDIxMTQzYWRiYjdhMzdiYmYzNmM0MzIxJA==",
"id": "709551ecd21143adbb7a37bbf36c4321",
"kind": "elasticsearch",
"ref_id": "elasticsearch",
"region": "ece-region"
}
]
},
{
"id": "83c2027d92c44aeba34378f44cf08137",
"name": "logging-and-metrics",
"resources": [
{
"cloud_id": "logging-and-metrics:MTkyLjE2OC40NC4xMC5pcC5lcy5pbzo5MjQzJDgzYzIwMjdkOTJjNDRhZWJhMzQzNzhmNDRjZjA4MTM3JGQxNDBiNmUzNWIwNDQ1YTlhZmQ0NDIwZjZjMWIzYjIx",
"id": "83c2027d92c44aeba34378f44cf08137",
"kind": "elasticsearch",
"ref_id": "elasticsearch",
"region": "ece-region"
},
{
"elasticsearch_cluster_ref_id": "elasticsearch",
"id": "d140b6e35b0445a9afd4420f6c1b3b21",
"kind": "kibana",
"ref_id": "kibana",
"region": "ece-region"
}
]
},
{
"id": "89a54cee4a2847c291f520ac00760886",
"name": "security-cluster",
"resources": [
{
"cloud_id": "security-cluster:MTkyLjE2OC40NC4xMC5pcC5lcy5pbzo5MjQzJDg5YTU0Y2VlNGEyODQ3YzI5MWY1MjBhYzAwNzYwODg2JA==",
"id": "89a54cee4a2847c291f520ac00760886",
"kind": "elasticsearch",
"ref_id": "elasticsearch",
"region": "ece-region"
}
]
}
]
}
`

func TestList(t *testing.T) {
type args struct {
params ListParams
}
tests := []struct {
name string
args args
want *models.DeploymentsListResponse
err error
}{
{
name: "fails on parameter validation",
err: util.ErrAPIReq,
},
{
name: "fails on API error",
args: args{params: ListParams{
API: api.NewMock(mock.New500Response(mock.NewStringBody("error"))),
}},
err: errors.New("unknown error (status 500)"),
},
{
name: "Succeeds",
args: args{params: ListParams{
API: api.NewMock(mock.New200Response(mock.NewStringBody(deploymentList))),
}},
want: &models.DeploymentsListResponse{Deployments: []*models.DeploymentsListingData{
{
ID: ec.String("709551ecd21143adbb7a37bbf36c4321"),
Name: ec.String("admin-console-elasticsearch"),
Resources: []*models.DeploymentResource{
{
CloudID: "admin-console-elasticsearch:MTkyLjE2OC40NC4xMC5pcC5lcy5pbzo5MjQzJDcwOTU1MWVjZDIxMTQzYWRiYjdhMzdiYmYzNmM0MzIxJA==",
ID: ec.String("709551ecd21143adbb7a37bbf36c4321"),
Kind: ec.String("elasticsearch"),
RefID: ec.String("elasticsearch"),
Region: ec.String("ece-region"),
},
},
},
{
ID: ec.String("83c2027d92c44aeba34378f44cf08137"),
Name: ec.String("logging-and-metrics"),
Resources: []*models.DeploymentResource{
{
CloudID: "logging-and-metrics:MTkyLjE2OC40NC4xMC5pcC5lcy5pbzo5MjQzJDgzYzIwMjdkOTJjNDRhZWJhMzQzNzhmNDRjZjA4MTM3JGQxNDBiNmUzNWIwNDQ1YTlhZmQ0NDIwZjZjMWIzYjIx",
ID: ec.String("83c2027d92c44aeba34378f44cf08137"),
Kind: ec.String("elasticsearch"),
RefID: ec.String("elasticsearch"),
Region: ec.String("ece-region"),
},
{
ElasticsearchClusterRefID: "elasticsearch",
ID: ec.String("d140b6e35b0445a9afd4420f6c1b3b21"),
Kind: ec.String("kibana"),
RefID: ec.String("kibana"),
Region: ec.String("ece-region"),
},
},
},
{
ID: ec.String("89a54cee4a2847c291f520ac00760886"),
Name: ec.String("security-cluster"),
Resources: []*models.DeploymentResource{
{
CloudID: "security-cluster:MTkyLjE2OC40NC4xMC5pcC5lcy5pbzo5MjQzJDg5YTU0Y2VlNGEyODQ3YzI5MWY1MjBhYzAwNzYwODg2JA==",
ID: ec.String("89a54cee4a2847c291f520ac00760886"),
Kind: ec.String("elasticsearch"),
RefID: ec.String("elasticsearch"),
Region: ec.String("ece-region"),
},
},
},
}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := List(tt.args.params)
if !reflect.DeepEqual(err, tt.err) {
t.Errorf("List() error = %v, wantErr %v", err, tt.err)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("List() = %+v, want %+v", got, tt.want)
}
})
}
}
23 changes: 23 additions & 0 deletions pkg/formatter/templates/bindata.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// text/allocator/showmetadata.gotmpl
// text/apm/list.gotmpl
// text/apm/planhistory.gotmpl
// text/deployment/list.gotmpl
// text/deployment/notelist.gotmpl
// text/deployment-template/list.gotmpl
// text/elasticsearch/list.gotmpl
Expand Down Expand Up @@ -261,6 +262,26 @@ func textApmPlanhistoryGotmpl() (*asset, error) {
return a, nil
}

var _textDeploymentListGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x91\x51\x6e\x82\x40\x10\x86\xdf\x3d\xc5\x64\xe3\xab\x7b\x80\x26\x3e\x6c\x85\xa4\xc4\x4a\x8c\x7a\x81\x81\x1d\x5a\x52\x58\x28\x2c\x4d\x1b\xc2\xdd\x1b\xd8\x1d\x2b\x6a\x13\x9f\x18\xbe\x99\x7f\xfe\x7f\xa0\xef\x57\xa0\x29\xcb\x0d\x81\xa8\xbe\xa8\x69\x72\x4d\x02\x86\xa1\xef\xa1\x41\xf3\x46\x20\x03\xaa\x8b\xea\xa7\x24\x63\x5b\xc7\xe9\x9b\xd2\xce\xd2\x89\xca\xba\x40\x4b\x20\x87\x61\x31\x62\xa3\x7d\x9f\x0b\xde\xab\x29\xc3\xae\xb0\xe3\xda\xc5\xe8\x27\xa2\xc0\x59\x58\x4c\xa6\x41\x11\xab\x5d\x28\x2e\x88\x08\x5f\xd5\xf1\x14\x6d\x8e\xa1\x3a\x6c\x5e\x66\x9d\x6d\xf4\xac\x62\x35\x43\x6a\xbf\xbb\x7a\xdf\x9f\x85\x93\xe1\xdd\x4b\xa6\xce\xf2\x23\x4f\xd0\x20\x3c\xad\x41\xac\x78\x7c\x89\x75\x79\x43\xea\x96\xb0\x49\xdf\xe7\xdc\x2f\x3e\x50\x5b\x75\x4d\x4a\xad\xc7\x79\x06\xf4\xd9\x61\x01\x72\x9b\x1b\x0d\xc2\x99\xf8\xcf\xca\x96\x6b\x90\x51\x30\x21\x32\xfa\x1f\x21\xd6\x25\xab\xc6\x4c\x8f\x49\x7c\xd2\x3f\x21\x47\xbf\x27\xe7\xea\xdc\xe2\x7f\x22\x63\x2c\xc9\xad\xb0\x98\x4c\x85\x8c\x82\xcb\x09\x3e\x64\x36\xe3\x82\xde\x20\x8e\x70\xe5\xea\x9e\xbf\x01\x00\x00\xff\xff\x78\x70\x0c\xba\x84\x02\x00\x00")

func textDeploymentListGotmplBytes() ([]byte, error) {
return bindataRead(
_textDeploymentListGotmpl,
"text/deployment/list.gotmpl",
)
}

func textDeploymentListGotmpl() (*asset, error) {
bytes, err := textDeploymentListGotmplBytes()
if err != nil {
return nil, err
}

info := bindataFileInfo{name: "text/deployment/list.gotmpl", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}

var _textDeploymentNotelistGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8e\xc1\x8e\x83\x20\x14\x45\xf7\x7e\x05\x61\x3f\xfc\xc3\x64\x24\x13\x17\x38\xc9\x88\x1f\x40\xcb\xd5\x98\x28\x1a\xc0\xa6\x09\xe1\xdf\x1b\xa4\xb8\xb0\x2b\x5e\xce\xe3\x9d\x7b\x43\xf8\x22\x1a\xc3\x64\x40\xe8\xfa\x80\xb5\x93\x06\x25\x31\x86\x40\xac\x32\x23\x08\x6b\x57\x0f\x97\x09\x9e\xb8\xef\x1e\x12\xcb\x36\x2b\x0f\xc2\x62\xac\x12\x36\xfa\xbd\x2f\x43\x31\x6a\x0c\x6a\x9f\x7d\x12\x56\x29\x89\xca\x46\xf0\xac\xf7\xea\x96\xff\xd2\x9f\x3f\x21\x78\x2b\x49\x53\x5f\x37\x7d\xc7\xff\xaf\x4c\xf0\xae\xfb\xfe\xe5\xa7\xf2\xd2\x32\xf5\x61\x72\x5a\xe0\xbc\x5a\xb6\x72\x7b\x9c\xb2\xa6\xce\x8e\x53\xc6\x7a\x07\xfb\x49\x05\x9c\x53\x23\x4a\x02\x8c\x3e\xa6\xfc\xbe\x02\x00\x00\xff\xff\x1a\x65\x9c\x45\x31\x01\x00\x00")

func textDeploymentNotelistGotmplBytes() ([]byte, error) {
Expand Down Expand Up @@ -740,6 +761,7 @@ var _bindata = map[string]func() (*asset, error){
"text/allocator/showmetadata.gotmpl": textAllocatorShowmetadataGotmpl,
"text/apm/list.gotmpl": textApmListGotmpl,
"text/apm/planhistory.gotmpl": textApmPlanhistoryGotmpl,
"text/deployment/list.gotmpl": textDeploymentListGotmpl,
"text/deployment/notelist.gotmpl": textDeploymentNotelistGotmpl,
"text/deployment-template/list.gotmpl": textDeploymentTemplateListGotmpl,
"text/elasticsearch/list.gotmpl": textElasticsearchListGotmpl,
Expand Down Expand Up @@ -817,6 +839,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"planhistory.gotmpl": &bintree{textApmPlanhistoryGotmpl, map[string]*bintree{}},
}},
"deployment": &bintree{nil, map[string]*bintree{
"list.gotmpl": &bintree{textDeploymentListGotmpl, map[string]*bintree{}},
"notelist.gotmpl": &bintree{textDeploymentNotelistGotmpl, map[string]*bintree{}},
}},
"deployment-template": &bintree{nil, map[string]*bintree{
Expand Down
15 changes: 15 additions & 0 deletions pkg/formatter/templates/text/deployment/list.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- define "override" }}{{ range .Deployments }}{{ executeTemplate .}}
{{ end }}{{ end }}{{ define "default" }}
{{- "ID" }}{{tab}}{{ "NAME"}}{{tab}}{{"ELASTICSEARCH"}}{{tab}}{{"KIBANA"}}{{tab}}{{"APM"}}{{tab}}{{"APPSEARCH"}}
{{- range .Deployments }}
{{- $kibana := "-"}}
{{- $apm := "-"}}
{{- $appsearch := "-"}}
{{- range .Resources}}
{{- if equal .Kind "kibana" }}{{ $kibana = .ID }}{{end}}
{{- if equal .Kind "apm" }}{{ $apm = .ID }}{{end}}
{{- if equal .Kind "appsearch" }}{{ $appsearch = .ID }}{{end}}
{{- end}}
{{ .ID }}{{tab}}{{ .Name }}{{ tab }}{{.ID}}{{tab}}{{ $kibana }}{{ tab }}{{ $apm }}{{ tab }}{{ $appsearch }}
{{- end}}
{{end}}
Loading

0 comments on commit a01959c

Please sign in to comment.