From 29772bd0a6dba06eb2c60ba0cb049c6599e7907a Mon Sep 17 00:00:00 2001 From: Maksym Postument <777rip777@gmail.com> Date: Thu, 23 Jul 2020 19:16:10 +0300 Subject: [PATCH] Elasticsearch (#3) --- README.MD | 15 +++++ cmd/elasticsearch.go | 76 ++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- modules/elasticSearchHelper/getTags.go | 62 +++++++++++++++++++++ modules/elasticSearchHelper/setTags.go | 42 ++++++++++++++ 6 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 cmd/elasticsearch.go create mode 100644 modules/elasticSearchHelper/getTags.go create mode 100644 modules/elasticSearchHelper/setTags.go diff --git a/README.MD b/README.MD index faf841c..eaa9828 100644 --- a/README.MD +++ b/README.MD @@ -15,6 +15,7 @@ awstaghelper allow tagging hundreds of AWS resources in few commands * [S3](#s3) * [ElastiCache](#elasticache) * [Redshift](#redshift) + * [ElasticSearch](#elasticsearch) * [Global parameters](#global-parameters) * [Contributing](#contributing) * [License](#license) @@ -114,6 +115,20 @@ Read csv and tag redshift - `awstaghelper redshift tag-redshift` Example: `awstaghelper redshift tag-redshift --filename redshiftTag.csv --profile main` +### ElasticSearch + +#### Get elasticsearch tags + +Get list of elasticsearch with required tags - `awstaghelper elasticsearch get-elasticsearch-tags` +Example: +`awstaghelper elasticsearch get-elasticsearch-tags --filename elasticsearchTag.csv --tags Name,Owner --profile main` + +#### Tag elasticsearch + +Read csv and tag elasticsearch - `awstaghelper elasticsearch tag-elasticsearch` +Example: +`awstaghelper elasticsearch tag-elasticsearch --filename elasticsearchTag.csv --profile main` + ## Global parameters `filename` - path where to write or read data. Supported by every option. Default `awsTags.csv` diff --git a/cmd/elasticsearch.go b/cmd/elasticsearch.go new file mode 100644 index 0000000..dd729b1 --- /dev/null +++ b/cmd/elasticsearch.go @@ -0,0 +1,76 @@ +/* +Copyright © 2020 Maksym Postument 777rip777@gmail.com + +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. +*/ +package cmd + +import ( + "awstaghelper/modules/common" + "awstaghelper/modules/elasticSearchHelper" + "fmt" + + "github.com/spf13/cobra" +) + +// elasticsearchCmd represents the elasticsearch command +var elasticsearchCmd = &cobra.Command{ + Use: "elasticsearch", + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("elasticsearch called") + }, +} + +var getElasticSearchCmd = &cobra.Command{ + Use: "get-elasticsearch-tags", + Short: "Write elasticsearch arn and required tags to csv", + Long: `Write to csv data with elasticsearch arn and required tags to csv. +This csv can be used with tag-elasticsearch command to tag aws environment. +Specify list of tags which should be read using tags flag: --tags Name,Env,Project. +Csv filename can be specified with flag filename.`, + Run: func(cmd *cobra.Command, args []string) { + tags, _ := cmd.Flags().GetString("tags") + filename, _ := cmd.Flags().GetString("filename") + profile, _ := cmd.Flags().GetString("profile") + region, _ := cmd.Flags().GetString("region") + sess := common.GetSession(region, profile) + common.WriteCsv(elasticSearchHelper.ParseElasticSearchTags(tags, *sess), filename) + }, +} + +var tagElasticSearchCmd = &cobra.Command{ + Use: "tag-elasticsearch", + Short: "Read csv and tag elasticsearch with csv data", + Long: `Read csv generated with get-elasticsearch-tags command and tag elasticsearch instances with tags from csv.`, + Run: func(cmd *cobra.Command, args []string) { + filename, _ := cmd.Flags().GetString("filename") + profile, _ := cmd.Flags().GetString("profile") + region, _ := cmd.Flags().GetString("region") + sess := common.GetSession(region, profile) + csvData := common.ReadCsv(filename) + elasticSearchHelper.TagElasticSearch(csvData, *sess) + }, +} + +func init() { + rootCmd.AddCommand(elasticsearchCmd) + elasticsearchCmd.AddCommand(getElasticSearchCmd) + elasticsearchCmd.AddCommand(tagElasticSearchCmd) +} diff --git a/go.mod b/go.mod index 5ea4302..df69434 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module awstaghelper go 1.14 require ( - github.com/aws/aws-sdk-go v1.33.9 + github.com/aws/aws-sdk-go v1.33.10 github.com/mitchellh/go-homedir v1.1.0 github.com/spf13/cobra v1.0.0 github.com/spf13/viper v1.7.0 diff --git a/go.sum b/go.sum index c1345bf..c1e6aeb 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.33.9 h1:nkC8YxL1nxwshIoO3UM2486Ph+zs7IZWjhRHjmXeCPw= -github.com/aws/aws-sdk-go v1.33.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.33.10 h1:W9pAK/NlveaJXzfcehkIQD7cQStEM0z2MrmTgdDY5BE= +github.com/aws/aws-sdk-go v1.33.10/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= diff --git a/modules/elasticSearchHelper/getTags.go b/modules/elasticSearchHelper/getTags.go new file mode 100644 index 0000000..879c5ae --- /dev/null +++ b/modules/elasticSearchHelper/getTags.go @@ -0,0 +1,62 @@ +package elasticSearchHelper + +import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/elasticsearchservice" + "github.com/aws/aws-sdk-go/service/sts" + "log" + "strings" +) + +// getInstances return all elasticsearch from specified region +func getInstances(session session.Session) *elasticsearchservice.ListDomainNamesOutput { + client := elasticsearchservice.New(&session) + input := &elasticsearchservice.ListDomainNamesInput{} + + result, err := client.ListDomainNames(input) + if err != nil { + log.Fatal("Not able to get instances", err) + } + return result +} + +// ParseElasticSearchTags parse output from getInstances and return arn and specified tags. +func ParseElasticSearchTags(tagsToRead string, session session.Session) [][]string { + instancesOutput := getInstances(session) + client := elasticsearchservice.New(&session) + stsClient := sts.New(&session) + callerIdentity, err := stsClient.GetCallerIdentity(&sts.GetCallerIdentityInput{}) + if err != nil { + log.Fatal("Not able to get elasticsearchservice tags", err) + } + var rows [][]string + headers := []string{"Arn"} + headers = append(headers, strings.Split(tagsToRead, ",")...) + rows = append(rows, headers) + for _, elasticCacheInstance := range instancesOutput.DomainNames { + + clusterArn := fmt.Sprintf("arn:aws:es:%s:%s:domain/%s", + *session.Config.Region, *callerIdentity.Account, *elasticCacheInstance.DomainName) + + input := &elasticsearchservice.ListTagsInput{ + ARN: aws.String(clusterArn), + } + elasticSearchTags, err := client.ListTags(input) + if err != nil { + fmt.Println("Not able to get elasticsearch tags", err) + } + tags := map[string]string{} + for _, tag := range elasticSearchTags.TagList { + tags[*tag.Key] = *tag.Value + } + + var resultTags []string + for _, key := range strings.Split(tagsToRead, ",") { + resultTags = append(resultTags, tags[key]) + } + rows = append(rows, append([]string{clusterArn}, resultTags...)) + } + return rows +} diff --git a/modules/elasticSearchHelper/setTags.go b/modules/elasticSearchHelper/setTags.go new file mode 100644 index 0000000..2cb15cd --- /dev/null +++ b/modules/elasticSearchHelper/setTags.go @@ -0,0 +1,42 @@ +package elasticSearchHelper + +import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/elasticsearchservice" +) + +// TagElasticSearch tag instances. Take as input data from csv file. Where first column id +func TagElasticSearch(csvData [][]string, session session.Session) { + client := elasticsearchservice.New(&session) + + var tags []*elasticsearchservice.Tag + for r := 1; r < len(csvData); r++ { + for c := 1; c < len(csvData[0]); c++ { + tags = append(tags, &elasticsearchservice.Tag{ + Key: &csvData[0][c], + Value: &csvData[r][c], + }) + } + + input := &elasticsearchservice.AddTagsInput{ + ARN: aws.String(csvData[r][0]), + TagList: tags, + } + + _, err := client.AddTags(input) + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + switch aerr.Code() { + default: + fmt.Println(aerr.Error()) + } + } else { + fmt.Println(err.Error()) + } + return + } + } +}