forked from cloudfoundry/bosh-bootloader
/
aws_update_lbs.go
155 lines (125 loc) · 4.28 KB
/
aws_update_lbs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package commands
import (
"errors"
"io/ioutil"
"strings"
"time"
"github.com/cloudfoundry/bosh-bootloader/storage"
)
type AWSUpdateLBs struct {
awsCreateLBs awsCreateLBs
certificateManager certificateManager
availabilityZoneRetriever availabilityZoneRetriever
infrastructureManager infrastructureManager
credentialValidator credentialValidator
logger logger
guidGenerator guidGenerator
stateStore stateStore
environmentValidator environmentValidator
}
func NewAWSUpdateLBs(awsCreateLBs awsCreateLBs, credentialValidator credentialValidator, certificateManager certificateManager,
availabilityZoneRetriever availabilityZoneRetriever, infrastructureManager infrastructureManager,
logger logger, guidGenerator guidGenerator, stateStore stateStore, environmentValidator environmentValidator) AWSUpdateLBs {
return AWSUpdateLBs{
awsCreateLBs: awsCreateLBs,
credentialValidator: credentialValidator,
certificateManager: certificateManager,
availabilityZoneRetriever: availabilityZoneRetriever,
infrastructureManager: infrastructureManager,
logger: logger,
guidGenerator: guidGenerator,
stateStore: stateStore,
environmentValidator: environmentValidator,
}
}
func (c AWSUpdateLBs) Execute(config AWSCreateLBsConfig, state storage.State) error {
err := c.credentialValidator.Validate()
if err != nil {
return err
}
err = c.environmentValidator.Validate(state)
if err != nil {
return err
}
if state.TFState != "" {
if config.Domain == "" {
config.Domain = state.LB.Domain
}
if config.LBType == "" {
config.LBType = state.LB.Type
}
return c.awsCreateLBs.Execute(config, state)
}
if !lbExists(state.Stack.LBType) {
return LBNotFound
}
if match, err := c.checkCertificateAndChain(config.CertPath, config.ChainPath, state.Stack.CertificateName); err != nil {
return err
} else if match {
c.logger.Println("no updates are to be performed")
return nil
}
c.logger.Step("uploading new certificate")
certificateName, err := certificateNameFor(state.Stack.LBType, c.guidGenerator, state.EnvID)
if err != nil {
return err
}
err = c.certificateManager.Create(config.CertPath, config.KeyPath, config.ChainPath, certificateName)
if err != nil {
return err
}
// Temporary fix for IAM propagation. Terraform should have retry logic for this, so we should remove it once we start using terraform on AWS.
time.Sleep(9 * time.Second)
if err := c.updateStack(certificateName, state.KeyPair.Name, state.Stack.Name, state.Stack.BOSHAZ, state.Stack.LBType, state.AWS.Region, state.EnvID); err != nil {
return err
}
c.logger.Step("deleting old certificate")
err = c.certificateManager.Delete(state.Stack.CertificateName)
if err != nil {
return err
}
state.Stack.CertificateName = certificateName
err = c.stateStore.Set(state)
if err != nil {
return err
}
return nil
}
func (c AWSUpdateLBs) checkCertificateAndChain(certPath string, chainPath string, oldCertName string) (bool, error) {
localCertificate, err := ioutil.ReadFile(certPath)
if err != nil {
return false, err
}
remoteCertificate, err := c.certificateManager.Describe(oldCertName)
if err != nil {
return false, err
}
if strings.TrimSpace(string(localCertificate)) != strings.TrimSpace(remoteCertificate.Body) {
return false, nil
}
if chainPath != "" {
localChain, err := ioutil.ReadFile(chainPath)
if err != nil {
return false, err
}
if strings.TrimSpace(string(localChain)) != strings.TrimSpace(remoteCertificate.Chain) {
return false, errors.New("you cannot change the chain after the lb has been created, please delete and re-create the lb with the chain")
}
}
return true, nil
}
func (c AWSUpdateLBs) updateStack(certificateName string, keyPairName string, stackName string, boshAZ string, lbType string, awsRegion, envID string) error {
availabilityZones, err := c.availabilityZoneRetriever.Retrieve(awsRegion)
if err != nil {
return err
}
certificate, err := c.certificateManager.Describe(certificateName)
if err != nil {
return err
}
_, err = c.infrastructureManager.Update(keyPairName, availabilityZones, stackName, boshAZ, lbType, certificate.ARN, envID)
if err != nil {
return err
}
return nil
}