@@ -2,39 +2,114 @@ package main
22
33import (
44 "fmt"
5+ "net/http"
6+ "time"
57
68 "github.com/aws/aws-sdk-go/aws"
9+ "github.com/aws/aws-sdk-go/aws/session"
710 "github.com/aws/aws-sdk-go/service/autoscaling"
811 "github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
912 "github.com/aws/aws-sdk-go/service/ec2"
1013 "github.com/aws/aws-sdk-go/service/ec2/ec2iface"
14+ yaml "gopkg.in/yaml.v2"
1115)
1216
13- // AWSClient allows you to get the list of IP addresses of instanes of an Auto Scaling group
17+ const upstreamNameErrorMsg = "The mandatory field name is either empty or missing for an upstream in the config file"
18+ const upstreamErrorMsgFormat = "The mandatory field %v is either empty or missing for the upstream %v in the config file"
19+ const upstreamPortErrorMsgFormat = "The mandatory field port is either zero or missing for the upstream %v in the config file"
20+ const upstreamKindErrorMsgFormat = "The mandatory field kind is either not equal to http or tcp or missing for the upstream %v in the config file"
21+
22+ // AWSClient allows you to get the list of IP addresses of instanes of an Auto Scaling group. It implements the CloudProvider interface
1423type AWSClient struct {
1524 svcEC2 ec2iface.EC2API
1625 svcAutoscaling autoscalingiface.AutoScalingAPI
26+ config * awsConfig
27+ }
28+
29+ // NewAWSClient creates and configures an AWSClient
30+ func NewAWSClient (data []byte ) (* AWSClient , error ) {
31+ awsClient := & AWSClient {}
32+ cfg , err := parseAWSConfig (data )
33+ if err != nil {
34+ return nil , fmt .Errorf ("error validating config: %v" , err )
35+ }
36+
37+ awsClient .config = cfg
38+
39+ err = awsClient .configure ()
40+ if err != nil {
41+ return nil , fmt .Errorf ("error configuring AWS Client: %v" , err )
42+ }
43+
44+ return awsClient , nil
45+ }
46+
47+ // GetUpstreams returns the Upstreams list
48+ func (client * AWSClient ) GetUpstreams () []Upstream {
49+ var upstreams []Upstream
50+ for _ , awsU := range client .config .Upstreams {
51+ u := Upstream {
52+ Name : awsU .Name ,
53+ Port : awsU .Port ,
54+ Kind : awsU .Kind ,
55+ ScalingGroup : awsU .AutoscalingGroup ,
56+ }
57+ upstreams = append (upstreams , u )
58+ }
59+ return upstreams
60+ }
61+
62+ // configure configures the AWSClient with necessary parameters
63+ func (client * AWSClient ) configure () error {
64+ httpClient := & http.Client {Timeout : connTimeoutInSecs * time .Second }
65+ cfg := & aws.Config {Region : aws .String (client .config .Region ), HTTPClient : httpClient }
66+
67+ session , err := session .NewSession (cfg )
68+ if err != nil {
69+ return err
70+ }
71+
72+ svcAutoscaling := autoscaling .New (session )
73+ svcEC2 := ec2 .New (session )
74+ client .svcEC2 = svcEC2
75+ client .svcAutoscaling = svcAutoscaling
76+ return nil
1777}
1878
19- // NewAWSClient creates an AWSClient
20- func NewAWSClient (svcEC2 ec2iface.EC2API , svcAutoscaling autoscalingiface.AutoScalingAPI ) * AWSClient {
21- return & AWSClient {svcEC2 , svcAutoscaling }
79+ // parseAWSConfig parses and validates AWSClient config
80+ func parseAWSConfig (data []byte ) (* awsConfig , error ) {
81+ cfg := & awsConfig {}
82+ err := yaml .Unmarshal (data , cfg )
83+ if err != nil {
84+ return nil , err
85+ }
86+
87+ err = validateAWSConfig (cfg )
88+ if err != nil {
89+ return nil , err
90+ }
91+
92+ return cfg , nil
2293}
2394
24- // CheckIfAutoscalingGroupExists checks if the Auto Scaling group exists
25- func (client * AWSClient ) CheckIfAutoscalingGroupExists (name string ) (bool , error ) {
95+ // CheckIfScalingGroupExists checks if the Auto Scaling group exists
96+ func (client * AWSClient ) CheckIfScalingGroupExists (name string ) (bool , error ) {
2697 _ , exists , err := client .getAutoscalingGroup (name )
27- return exists , err
98+ if err != nil {
99+ return exists , fmt .Errorf ("couldn't check if an AutoScaling group exists: %v" , err )
100+ }
101+ return exists , nil
28102}
29103
30- // GetPrivateIPsOfInstancesOfAutoscalingGroup returns the list of IP addresses of instanes of the Auto Scaling group
31- func (client * AWSClient ) GetPrivateIPsOfInstancesOfAutoscalingGroup (name string ) ([]string , error ) {
104+ // GetPrivateIPsForScalingGroup returns the list of IP addresses of instanes of the Auto Scaling group
105+ func (client * AWSClient ) GetPrivateIPsForScalingGroup (name string ) ([]string , error ) {
32106 group , exists , err := client .getAutoscalingGroup (name )
33107 if err != nil {
34108 return nil , err
35109 }
110+
36111 if ! exists {
37- return nil , fmt .Errorf ("autoscaling group %v doesn't exists " , name )
112+ return nil , fmt .Errorf ("autoscaling group %v doesn't exist " , name )
38113 }
39114
40115 instances , err := client .getInstancesOfAutoscalingGroup (group )
@@ -96,3 +171,44 @@ func (client *AWSClient) getInstancesOfAutoscalingGroup(group *autoscaling.Group
96171
97172 return result , nil
98173}
174+
175+ // Configuration for AWS Cloud Provider
176+
177+ type awsConfig struct {
178+ Region string
179+ Upstreams []awsUpstream
180+ }
181+
182+ type awsUpstream struct {
183+ Name string
184+ AutoscalingGroup string `yaml:"autoscaling_group"`
185+ Port int
186+ Kind string
187+ }
188+
189+ func validateAWSConfig (cfg * awsConfig ) error {
190+ if cfg .Region == "" {
191+ return fmt .Errorf (errorMsgFormat , "region" )
192+ }
193+
194+ if len (cfg .Upstreams ) == 0 {
195+ return fmt .Errorf ("There are no upstreams found in the config file" )
196+ }
197+
198+ for _ , ups := range cfg .Upstreams {
199+ if ups .Name == "" {
200+ return fmt .Errorf (upstreamNameErrorMsg )
201+ }
202+ if ups .AutoscalingGroup == "" {
203+ return fmt .Errorf (upstreamErrorMsgFormat , "autoscaling_group" , ups .Name )
204+ }
205+ if ups .Port == 0 {
206+ return fmt .Errorf (upstreamPortErrorMsgFormat , ups .Name )
207+ }
208+ if ups .Kind == "" || ! (ups .Kind == "http" || ups .Kind == "stream" ) {
209+ return fmt .Errorf (upstreamKindErrorMsgFormat , ups .Name )
210+ }
211+ }
212+
213+ return nil
214+ }
0 commit comments