Skip to content

Commit

Permalink
Release 0.2.0 (#4)
Browse files Browse the repository at this point in the history
* Merge branch 'develop' of github.com:darkraiden/sigmund into develop

# Conflicts:
#	.gitignore
#	go.mod
#	pkg/autoscaling/execPolicy.go

* add salvatore to contributors

* add changelog
  • Loading branch information
Davide Di Mauro committed May 29, 2019
1 parent bb356d6 commit b0cc6d6
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 108 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/.vscode
/vendor
.vscode
vendor
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## 0.2.0 (May 29, 2019)

ADDITIONS:

- checks if either `Memory` or `CPU` are in an `OK` state, rather than just `Low`

CHANGES:

- Minor code improvements
1 change: 1 addition & 0 deletions contributors.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- [Davide Di Mauro](https://github.com/darkraiden)
- [Salvatore Tards](https://github.com/Stakct)
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ module github.com/darkraiden/sigmund
require (
github.com/aws/aws-lambda-go v1.8.0
github.com/aws/aws-sdk-go v1.15.89
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8
github.com/sirupsen/logrus v1.4.2
)
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,18 @@ github.com/aws/aws-lambda-go v1.8.0 h1:YMCzi9FP7MNVVj9AkGpYyaqh/mvFOjhqiDtnNlWtK
github.com/aws/aws-lambda-go v1.8.0/go.mod h1:zUsUQhAUjYzR8AuduJPCfhBuKWUaDbQiPOG+ouzmE1A=
github.com/aws/aws-sdk-go v1.15.89 h1:T5xLl6ePbLhTdKWoeRhwIV58OfXPSLu2s4GMNDpRLu0=
github.com/aws/aws-sdk-go v1.15.89/go.mod h1:es1KtYUFs7le0xQ3rOihkuoVD90z7D0fR2Qm4S00/gU=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/magefile/mage v1.8.0/go.mod h1:IUDi13rsHje59lecXokTfGX0QIzO45uVPlXnJYsXepA=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/net v0.0.0-20181207154023-610586996380/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
70 changes: 58 additions & 12 deletions metrics.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,65 @@
package sigmund

import (
"fmt"
log "github.com/sirupsen/logrus"
)

func identifyMetric(m string) (string, error) {
var k string
var err error
switch {
case m == "memory":
k = "isLowMemory"
case m == "cpu":
k = "isLowCPU"
default:
err = fmt.Errorf("%v is an invalid parameter. Please provide either 'memory' or 'cpu' keys", m)
// Metric is a type that will be used to serialise the metric types received from SNS
type Metric int

type dbKey struct {
metric string
value bool
}

const (
// LowMemory is a metric that indicates low memory
LowMemory Metric = iota
// LowCPU is a metric that indicates low CPU
LowCPU
// OkMemory is a metric that indicates the absence of memory issues
OkMemory
// OkCPU is a metric that indicates the absence of CPU issues
OkCPU
)

var stringsToMetrics = map[string]Metric{
"LowMemory": LowMemory,
"LowCPU": LowCPU,
"OkMemory": OkMemory,
"OkCPU": OkCPU,
}

func (m Metric) String() string {
metricNames := [...]string{
"LowMemory",
"LowCPU",
"OkMemory",
"OkCPU",
}

if m < 0 || m > 3 {
log.WithField("integer", m).Panic("Value cannot be interpreted as a metric")
}
return k, err

return metricNames[m]
}

var metricsTodbKey = map[Metric]dbKey{
LowMemory: {
metric: "isLowMemory",
value: true,
},
LowCPU: {
metric: "isLowCPU",
value: true,
},
OkMemory: {
metric: "isLowMemory",
value: false,
},
OkCPU: {
metric: "isLowCPU",
value: false,
},
}
28 changes: 28 additions & 0 deletions pkg/autoscaling/errorHandlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package autoscaling

import (
"fmt"

"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/autoscaling"
)

func checkAutoscalingError(err error) error {
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case autoscaling.ErrCodeScalingActivityInProgressFault:
return fmt.Errorf("%v: %v", autoscaling.ErrCodeScalingActivityInProgressFault, aerr.Error())
case autoscaling.ErrCodeResourceContentionFault:
return fmt.Errorf("%v: %v", autoscaling.ErrCodeResourceContentionFault, aerr.Error())
default:
return fmt.Errorf("%v", aerr.Error())
}
} else {
// Print the error, cast err to awserr.Error to get the Code and
// Message from an error.
return err
}
}
return nil
}
26 changes: 2 additions & 24 deletions pkg/autoscaling/execPolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/autoscaling"
)

Expand All @@ -16,30 +15,9 @@ func (client *Client) TriggerPolicy(asg *Autoscaling) error {
PolicyName: aws.String(asg.PolicyName),
}

_, err := client.ExecutePolicy(input)
result, err := client.ExecutePolicy(input)
awsErr := checkAutoscalingError(err)

fmt.Println(result)
return awsErr
}

func checkAutoscalingError(err error) error {
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case autoscaling.ErrCodeScalingActivityInProgressFault:
return fmt.Errorf("%v: %v", autoscaling.ErrCodeScalingActivityInProgressFault, aerr.Error())
case autoscaling.ErrCodeResourceContentionFault:
return fmt.Errorf("%v: %v", autoscaling.ErrCodeResourceContentionFault, aerr.Error())
default:
return fmt.Errorf("%v", aerr.Error())
}
} else {
// Print the error, cast err to awserr.Error to get the Code and
// Message from an error.//^
//I would probably rewrite this to make the default be to return error and handle the specific cases you're interested in here.
//Wrapping a switch in an if is tough to read.
return err
}
}
return nil
}
92 changes: 58 additions & 34 deletions shrinker.go
Original file line number Diff line number Diff line change
@@ -1,61 +1,83 @@
package sigmund

import (
log "github.com/sirupsen/logrus"

"github.com/darkraiden/sigmund/pkg/autoscaling"
"github.com/darkraiden/sigmund/pkg/storage/dynamo"
)

// Shrink is the core function of the package
// which Executes an Autoscaling Group Policy
// when requirements are met
func (s *Sigmund) Shrink() error {
var item *DBItem
dbClient, err := s.newDBClient()
func (s *Sigmund) Shrink() {
dbClient, err := s.newDBClient(metricsTodbKey[s.Key].metric)
if err != nil {
return err
s.Log.WithError(err).Panic("Could not connect to DynamoDB")
}

// Run a Select query
item, err = s.readDynamo(dbClient)
if err != nil {
return err
s.Log.WithError(err).Panic("Could not read from DynamoDB")
}

switch s.Dynamo.Key {
case "isLowCPU":
if !item.IsLowCPU {
err = dbClient.WriteToTable(s.Dynamo.TableName, s.Dynamo.Key, true)
if err != nil {
return err
}
item.IsLowCPU = true
switch s.Dynamo.Key.String() {
case "LowMemory":
err := dbClient.WriteToTable(s.Dynamo.TableName, "isLowMemory", true)
if err != nil {
s.Log.WithError(err).WithFields(log.Fields{
"table name": s.Dynamo.TableName,
"metric": "isLowMemory == true",
}).Panic()
}
item.IsLowMemory = true
case "OkMemory":
err := dbClient.WriteToTable(s.Dynamo.TableName, "isLowMemory", false)
if err != nil {
s.Log.WithError(err).WithFields(log.Fields{
"table name": s.Dynamo.TableName,
"metric": "isLowMemory == false",
}).Panic()
}
case "isLowMemory":
if !item.IsLowMemory {
err = dbClient.WriteToTable(s.Dynamo.TableName, s.Dynamo.Key, true)
if err != nil {
return err
}
item.IsLowMemory = true
item.IsLowMemory = false
case "LowCPU":
err := dbClient.WriteToTable(s.Dynamo.TableName, "isLowCPU", true)
if err != nil {
s.Log.WithError(err).WithFields(log.Fields{
"table name": s.Dynamo.TableName,
"metric": "isLowCPU == true",
}).Panic()
}
item.IsLowCPU = true
case "OkCPU":
err := dbClient.WriteToTable(s.Dynamo.TableName, "isLowCPU", false)
if err != nil {
s.Log.WithError(err).WithFields(log.Fields{
"table name": s.Dynamo.TableName,
"metric": "isLowCPU == false",
}).Panic()
}
}

if item.IsLowCPU && item.IsLowMemory {
err = dbClient.WriteToTable(s.Dynamo.TableName, "isLowCPU", false)
if err != nil {
return err
s.Log.WithError(err).WithFields(log.Fields{
"table name": s.Dynamo.TableName,
"metric": "isLowCPU == false",
}).Panic()
}
err = dbClient.WriteToTable(s.Dynamo.TableName, "isLowMemory", false)
if err != nil {
return err
}
err = s.execASGPolicy()
if err != nil {
return err
s.Log.WithError(err).WithFields(log.Fields{
"table name": s.Dynamo.TableName,
"metric": "isLowMemory == false",
}).Panic()
}
s.execASGPolicy()
}

return nil
}

func (s *Sigmund) newDBClient() (*dynamo.Client, error) {
Expand Down Expand Up @@ -85,22 +107,24 @@ func (s *Sigmund) readDynamo(cli *dynamo.Client) (*DBItem, error) {
}, nil
}

func (s *Sigmund) execASGPolicy() error {
func (s *Sigmund) execASGPolicy() {
var client *autoscaling.Client
asg, err := autoscaling.New(s.Autoscaling.AutoScalingGroupName, s.Autoscaling.PolicyName, s.Autoscaling.Region)
if err != nil {
return err
s.Log.WithError(err).WithFields(log.Fields{
"asg name": s.Autoscaling.AutoScalingGroupName,
"policy name": s.Autoscaling.PolicyName,
"region": s.Autoscaling.Region,
}).Panic("Failed to create autoscaling config")
}

client, err = asg.NewClient()
if err != nil {
return err
s.Log.WithError(err).Panic("Failed to create autoscaling client")
}

err = client.TriggerPolicy(asg)
if err != nil {
return err
s.Log.WithError(err).Panic("Failed to trigger asg policy")
}

return nil
}
Loading

0 comments on commit b0cc6d6

Please sign in to comment.