@@ -2,39 +2,114 @@ package main
2
2
3
3
import (
4
4
"fmt"
5
+ "net/http"
6
+ "time"
5
7
6
8
"github.com/aws/aws-sdk-go/aws"
9
+ "github.com/aws/aws-sdk-go/aws/session"
7
10
"github.com/aws/aws-sdk-go/service/autoscaling"
8
11
"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
9
12
"github.com/aws/aws-sdk-go/service/ec2"
10
13
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
14
+ yaml "gopkg.in/yaml.v2"
11
15
)
12
16
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
14
23
type AWSClient struct {
15
24
svcEC2 ec2iface.EC2API
16
25
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
17
77
}
18
78
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
22
93
}
23
94
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 ) {
26
97
_ , 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
28
102
}
29
103
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 ) {
32
106
group , exists , err := client .getAutoscalingGroup (name )
33
107
if err != nil {
34
108
return nil , err
35
109
}
110
+
36
111
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 )
38
113
}
39
114
40
115
instances , err := client .getInstancesOfAutoscalingGroup (group )
@@ -96,3 +171,44 @@ func (client *AWSClient) getInstancesOfAutoscalingGroup(group *autoscaling.Group
96
171
97
172
return result , nil
98
173
}
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