Skip to content

Commit

Permalink
Implemented delete
Browse files Browse the repository at this point in the history
  • Loading branch information
mariotoffia committed Oct 28, 2020
1 parent e677ffa commit 5dff64d
Show file tree
Hide file tree
Showing 15 changed files with 607 additions and 182 deletions.
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
"Childs",
"Msgf",
"Printf",
"Prms",
"Upsert",
"Wrapf",
"accountingdb",
"asmsub",
"awscfg",
"awsutil",
"banna",
"batchsize",
Expand All @@ -16,17 +20,21 @@
"dbctx",
"dbname",
"dbtimeout",
"dprm",
"dreq",
"eval",
"fqname",
"g",
"gurka",
"gurkaburka",
"gördis",
"hasnoprefix",
"hunden",
"kalle",
"keyid",
"mariotoffia",
"mydb",
"myname",
"nasse",
"nisse",
"omitempty",
Expand Down
76 changes: 76 additions & 0 deletions delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package ssm

import (
"reflect"

"github.com/mariotoffia/ssm/internal/asm"
"github.com/mariotoffia/ssm/internal/pms"
"github.com/mariotoffia/ssm/parser"
"github.com/mariotoffia/ssm/support"
)

func (s *Serializer) delete(v interface{},
filter *support.FieldFilters,
usage []Usage) (map[string]support.FullNameField, *parser.StructNode, error) {

if len(usage) == 0 {
if len(s.usage) > 0 {
usage = s.usage
} else {
usage = []Usage{UsePms, UseAsm}
}
}

if nil == filter {
filter = support.NewFilters()
}

tp := reflect.ValueOf(v)
prs := parser.New(s.service, s.env, s.prefix)

if _, found := find(usage, UsePms); found {
prs.RegisterTagParser("pms", pms.NewTagParser())
}
if _, found := find(usage, UseAsm); found {
prs.RegisterTagParser("asm", asm.NewTagParser())
}

for n, v := range s.parser {
prs.RegisterTagParser(n, v)
}

node, err := prs.Parse(tp)
if err != nil {
return nil, nil, err
}

var invalid map[string]support.FullNameField

if _, found := find(usage, UsePms); found {
pmsRepository, err := s.getAndConfigurePms()
if err != nil {
return nil, nil, err
}

invalid, err = pmsRepository.Delete(node, filter)
}

if _, found := find(usage, UseAsm); found {
asmRepository, err := s.getAndConfigureAsm()
if err != nil {
return nil, nil, err
}

invalid2, err := asmRepository.Delete(node, filter)
if invalid == nil && len(invalid2) > 0 {
invalid = map[string]support.FullNameField{}
}

// Merge field errors from ASM with PMS errors
for key, value := range invalid2 {
invalid[key] = value
}
}

return invalid, node, err
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
module github.com/mariotoffia/ssm

require (
github.com/aws/aws-sdk-go v1.35.16
github.com/aws/aws-sdk-go-v2 v0.22.0
github.com/google/uuid v1.1.1
github.com/kr/pretty v0.1.0 // indirect
github.com/pkg/errors v0.8.1
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.18.0
github.com/stretchr/testify v1.5.1
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
Expand Down
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/aws/aws-sdk-go v1.35.16 h1:kaYAh0lYwMUTmb/t6whBkj2nZzi3yAeQuwv0QB6dQcg=
github.com/aws/aws-sdk-go v1.35.16/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
github.com/aws/aws-sdk-go-v2 v0.22.0 h1:mlixfS5HVzn7Sf3KVhjAIM2H3bB7uoTbLCtKHvteUfE=
github.com/aws/aws-sdk-go-v2 v0.22.0/go.mod h1:2LhT7UgHOXK3UXONKI5OMgIyoQL6zTAw/jwIeX6yqzw=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
Expand All @@ -10,13 +12,18 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
Expand Down Expand Up @@ -44,3 +51,5 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
133 changes: 133 additions & 0 deletions internal/asm/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package asm

import (
"context"
"fmt"
"strings"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/awserr"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/mariotoffia/ssm/parser"
"github.com/mariotoffia/ssm/support"
"github.com/rs/zerolog/log"
)

// Delete will delete the paths found in nodes.
func (p *Serializer) Delete(
node *parser.StructNode,
filter *support.FieldFilters) (map[string]support.FullNameField, error) {

m := map[string]*parser.StructNode{}
svc := secretsmanager.New(p.config)

parser.NodesToParameterMap(node, m, filter, []string{"asm"})

im := map[string]support.FullNameField{}
paths := parser.ExtractPaths(m)

for _, path := range paths {

err := internalDelete(
svc,
secretsmanager.DeleteSecretInput{SecretId: aws.String(path),
ForceDeleteWithoutRecovery: aws.Bool(true)},
)

if err != nil {

if val, ok := m[path]; ok {
im[val.FqName] = support.FullNameField{
RemoteName: path,
LocalName: val.FqName,
Field: val.Field,
Value: val.Value,
Error: err,
}
}

}
}

return im, nil
}

// DeleteTree will delete all secrets that have a certain prefix.
// Since it is possible to specify many _prefixes_ this is able
// to delete several trees.
func (p *Serializer) DeleteTree(prefixes ...string) error {

svc := secretsmanager.New(p.config)
input := secretsmanager.ListSecretsInput{}

for {

req := svc.ListSecretsRequest(&input)
resp, err := req.Send(context.Background())

if err != nil {

log.Warn().Msgf("Failed to list asm-secrets %v", err)
break

}

input.NextToken = resp.NextToken

for _, s := range resp.SecretList {

log.Debug().Msgf("Found asm-secret %s", *s.Name)

if findPrefix(prefixes, *s.Name) {

internalDelete(
svc,
secretsmanager.DeleteSecretInput{SecretId: aws.String(*s.Name),
ForceDeleteWithoutRecovery: aws.Bool(true)},
)

}

}

if resp.NextToken == nil {

log.Debug().Msg("No more asm-secrets to delete (note that you may to delete them some minutes after creation to be found!")
break

}

input.NextToken = resp.NextToken
}

return nil
}

func findPrefix(array []string, val string) bool {

for _, item := range array {
if strings.HasPrefix(val, item) {
return true
}
}

return false
}

func internalDelete(svc *secretsmanager.Client, prms secretsmanager.DeleteSecretInput) error {

fmt.Printf("deleting-asm %v", prms)
req := svc.DeleteSecretRequest(&prms)
if _, err := req.Send(context.Background()); err != nil {
if awserr, ok := err.(awserr.Error); ok {
switch awserr.Code() {
case secretsmanager.ErrCodeResourceNotFoundException:
break
default:
log.Warn().Msgf("Error when deleting %v", prms)
return err
}
}
}
return nil
}
88 changes: 88 additions & 0 deletions internal/pms/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package pms

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ssm"
"github.com/mariotoffia/ssm/parser"
"github.com/mariotoffia/ssm/support"
"github.com/rs/zerolog/log"
)

// Delete will delete all paths described by _node_ tree. This is the
// "inverse" of `Get`.
func (p *Serializer) Delete(node *parser.StructNode,
filter *support.FieldFilters) (map[string]support.FullNameField, error) {

m := map[string]*parser.StructNode{}
parser.NodesToParameterMap(node, m, filter, []string{"pms"})
paths := parser.ExtractPaths(m)

client := ssm.New(p.config)

input := ssm.DeleteParametersInput{
Names: paths,
}

req := client.DeleteParametersRequest(&input)
result, err := req.Send(context.Background())
if err != nil {
return nil, err
}

im := p.handleInvalidRequestParameters(result.InvalidParameters, m, "delete")

return im, nil
}

// DeleteTree lists all parameters that begins with a certain _prefix_
// and deletes those.
//
// This function accepts a set of prefixes and therefore may delete several
// trees.
func (p *Serializer) DeleteTree(prefixes ...string) error {

inp := ssm.DescribeParametersInput{
ParameterFilters: []ssm.ParameterStringFilter{{
Key: aws.String("Name"),
Option: aws.String("BeginsWith"),
Values: prefixes,
}}}

client := ssm.New(p.config)

for {
req := client.DescribeParametersRequest(&inp)
res, err := req.Send(context.Background())
if err != nil {
log.Warn().Msgf("got error when listing params for deletion error: %v", err)
return err
}

dprm := ssm.DeleteParametersInput{}
for _, prm := range res.Parameters {
log.Debug().Msgf("Deleting pms-param name: %s version %d", *prm.Name, *prm.Version)
dprm.Names = append(dprm.Names, *prm.Name)
}

if len(dprm.Names) > 0 {
dreq := client.DeleteParametersRequest(&dprm)
_, err = dreq.Send(context.Background())
if err != nil {
log.Warn().Msgf("got error when deleting params error: %v", err)
return err
}
} else {
log.Debug().Msgf("No pms-parameters to delete")
}

if res.NextToken == nil {
break
}

inp.NextToken = res.NextToken
}

return nil
}
Loading

0 comments on commit 5dff64d

Please sign in to comment.