Skip to content

Commit 16b4d6c

Browse files
committed
use intermediate DNS names and remove Terraform lookup
1 parent b74500f commit 16b4d6c

File tree

6 files changed

+45
-218
lines changed

6 files changed

+45
-218
lines changed

cmd/cli/flags/flags.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ const (
1818

1919
// Persistent flags for multiregion commands
2020
const (
21-
DomainName = "domain-name"
22-
Env = "env"
23-
Region2 = "region2"
24-
TfcToken = "tfc-token"
25-
OrgAlternate = "org-alternate"
26-
TfcTokenAlternate = "tfc-token-alternate"
21+
DomainName = "domain-name"
22+
Env = "env"
23+
Region2 = "region2"
24+
TfcToken = "tfc-token"
2725
)
2826

2927
func NewStringFlag(command *cobra.Command, name, shorthand string, value, usage string) {

cmd/cli/multiregion/dns.go

+36-177
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,21 @@ import (
1010
"log"
1111

1212
"github.com/cloudflare/cloudflare-go"
13-
"github.com/hashicorp/go-tfe"
1413
"github.com/spf13/cobra"
1514
"github.com/spf13/viper"
1615

1716
"github.com/silinternational/idp-cli/cmd/cli/flags"
1817
)
1918

2019
type DnsCommand struct {
21-
cfClient *cloudflare.API
22-
cfZone *cloudflare.ResourceContainer
23-
domainName string
24-
failback bool
25-
tfcOrg string
26-
tfcOrgAlt string
27-
tfcToken string
28-
tfcTokenAlt string
29-
testMode bool
20+
cfClient *cloudflare.API
21+
cfZone *cloudflare.ResourceContainer
22+
domainName string
23+
env string
24+
failback bool
25+
region string
26+
region2 string
27+
testMode bool
3028
}
3129

3230
type DnsValues struct {
@@ -60,8 +58,7 @@ func runDnsCommand(failback bool) {
6058

6159
d := newDnsCommand(pFlags, failback)
6260

63-
values := d.getDnsValuesFromTfc(pFlags)
64-
d.setDnsRecordValues(pFlags.idp, values)
61+
d.setDnsRecordValues(pFlags.idp)
6562
}
6663

6764
func newDnsCommand(pFlags PersistentFlags, failback bool) *DnsCommand {
@@ -92,57 +89,58 @@ func newDnsCommand(pFlags PersistentFlags, failback bool) *DnsCommand {
9289
fmt.Printf("Using domain name %s with ID %s\n", d.domainName, zoneID)
9390
d.cfZone = cloudflare.ZoneIdentifier(zoneID)
9491

95-
d.tfcToken = pFlags.tfcToken
96-
d.tfcTokenAlt = pFlags.tfcTokenAlt
97-
d.tfcOrg = pFlags.org
98-
d.tfcOrgAlt = pFlags.orgAlt
92+
d.env = pFlags.env
93+
d.region = pFlags.region
94+
d.region2 = pFlags.secondaryRegion
95+
9996
d.failback = failback
10097

10198
return &d
10299
}
103100

104-
func (d *DnsCommand) setDnsRecordValues(idpKey string, dnsValues DnsValues) {
101+
func (d *DnsCommand) setDnsRecordValues(idpKey string) {
105102
if d.failback {
106103
fmt.Println("Setting DNS records to primary region...")
107104
} else {
108105
fmt.Println("Setting DNS records to secondary region...")
109106
}
110107

108+
region := d.region2
109+
if d.failback {
110+
region = d.region
111+
}
112+
113+
supportBotName := "sherlock"
114+
if d.env != "prod" {
115+
supportBotName = "watson"
116+
}
117+
111118
dnsRecords := []struct {
112-
name string
113-
valueFlag string
114-
tfcValue string
119+
name string
120+
value string
115121
}{
116122
// "mfa-api" is the TOTP API, also known as serverless-mfa-api
117-
{"mfa-api", "mfa-api-value", dnsValues.mfa},
123+
{"mfa-api", "mfa-api-" + region},
118124

119125
// "twosv-api" is the Webauthn API, also known as serverless-mfa-api-go
120-
{"twosv-api", "twosv-api-value", dnsValues.twosv},
126+
{"twosv-api", "twosv-api-" + region},
121127

122-
// "support-bot" is the idp-support-bot API that is configured in the Slack API dashboard
123-
{"sherlock", "support-bot-value", dnsValues.bot},
128+
// this is the idp-support-bot API that is configured in the Slack API dashboard
129+
{supportBotName, supportBotName + "-" + region},
124130

125131
// ECS services
126-
{idpKey + "-email", "email-service-value", dnsValues.albInternal},
127-
{idpKey + "-broker", "id-broker-value", dnsValues.albInternal},
128-
{idpKey + "-pw-api", "pw-api-value", dnsValues.albExternal},
129-
{idpKey, "ssp-value", dnsValues.albExternal},
130-
{idpKey + "-sync", "id-sync-value", dnsValues.albExternal},
132+
{idpKey + "-email", idpKey + "-email-" + region},
133+
{idpKey + "-broker", idpKey + "-broker-" + region},
134+
{idpKey + "-pw-api", idpKey + "-pw-api-" + region},
135+
{idpKey, idpKey + "-" + region},
136+
{idpKey + "-sync", idpKey + "-sync-" + region},
131137
}
132138

133139
for _, record := range dnsRecords {
134-
value := getDnsValue(record.valueFlag, record.tfcValue)
135-
d.setCloudflareCname(record.name, value)
140+
d.setCloudflareCname(record.name, record.value)
136141
}
137142
}
138143

139-
func getDnsValue(valueFlag, tfcValue string) string {
140-
if tfcValue != "" {
141-
return tfcValue
142-
}
143-
return viper.GetString(valueFlag)
144-
}
145-
146144
func (d *DnsCommand) setCloudflareCname(name, value string) {
147145
if value == "" {
148146
fmt.Printf(" skipping %s (no value provided)\n", name)
@@ -186,142 +184,3 @@ func (d *DnsCommand) setCloudflareCname(name, value string) {
186184
log.Fatalf("error updating DNS record %s: %s", name, err)
187185
}
188186
}
189-
190-
func (d *DnsCommand) getDnsValuesFromTfc(pFlags PersistentFlags) (values DnsValues) {
191-
ctx := context.Background()
192-
193-
var clusterWorkspaceName string
194-
if d.failback {
195-
clusterWorkspaceName = clusterWorkspace(pFlags)
196-
} else {
197-
clusterWorkspaceName = clusterSecondaryWorkspace(pFlags)
198-
}
199-
200-
internal, external := d.getAlbValuesFromTfc(ctx, clusterWorkspaceName)
201-
values.albInternal = internal
202-
values.albExternal = external
203-
204-
bot := "idp-support-bot-prod"
205-
if pFlags.env != envProd {
206-
bot = "idp-support-bot-dev" // TODO: consider renaming the workspace name so this can be simplified
207-
}
208-
values.bot = d.getLambdaDnsValueFromTfc(ctx, bot)
209-
210-
twosv := "serverless-mfa-api-go-prod"
211-
if pFlags.env != envProd {
212-
twosv = "serverless-mfa-api-go-dev" // TODO: consider renaming the workspace name so this can be simplified
213-
}
214-
values.twosv = d.getLambdaDnsValueFromTfc(ctx, twosv)
215-
216-
mfa := "serverless-mfa-api-prod"
217-
if pFlags.env != envProd {
218-
mfa = "serverless-mfa-api-dev" // TODO: consider renaming the workspace name so this can be simplified
219-
}
220-
values.mfa = d.getLambdaDnsValueFromTfc(ctx, mfa)
221-
return
222-
}
223-
224-
func (d *DnsCommand) getAlbValuesFromTfc(ctx context.Context, workspaceName string) (internal, external string) {
225-
workspaceID, client, err := d.findTfcWorkspace(ctx, workspaceName)
226-
if err != nil {
227-
fmt.Printf("Failed to get ALB DNS values: %s\n Will use DNS config values if provided.\n", err)
228-
return
229-
}
230-
231-
outputs, err := client.StateVersionOutputs.ReadCurrent(ctx, workspaceID)
232-
if err != nil {
233-
fmt.Printf("Error reading Terraform state outputs on workspace %s: %s", workspaceName, err)
234-
return
235-
}
236-
237-
for _, item := range outputs.Items {
238-
itemValue, _ := item.Value.(string)
239-
switch item.Name {
240-
case "alb_dns_name":
241-
external = itemValue
242-
case "internal_alb_dns_name":
243-
internal = itemValue
244-
}
245-
}
246-
return
247-
}
248-
249-
func (d *DnsCommand) getLambdaDnsValueFromTfc(ctx context.Context, workspaceName string) string {
250-
outputName := "secondary_region_domain_name"
251-
if d.failback {
252-
outputName = "primary_region_domain_name"
253-
}
254-
val, err := d.getTfcOutputFromWorkspace(ctx, workspaceName, outputName)
255-
if err != nil {
256-
fmt.Printf("Error: %s\n Will use config value if provided.\n", err)
257-
return ""
258-
}
259-
return val
260-
}
261-
262-
func (d *DnsCommand) getTfcOutputFromWorkspace(ctx context.Context, workspaceName, outputName string) (string, error) {
263-
workspaceID, client, err := d.findTfcWorkspace(ctx, workspaceName)
264-
if err != nil {
265-
return "", fmt.Errorf("failed to get DNS value from %s: %w", workspaceName, err)
266-
}
267-
268-
outputs, err := client.StateVersionOutputs.ReadCurrent(ctx, workspaceID)
269-
if err != nil {
270-
return "", fmt.Errorf("error reading Terraform state outputs on workspace %s: %w", workspaceName, err)
271-
}
272-
273-
for _, item := range outputs.Items {
274-
if item.Name == outputName {
275-
if itemValue, ok := item.Value.(string); ok {
276-
return itemValue, nil
277-
}
278-
break
279-
}
280-
}
281-
282-
return "", fmt.Errorf("value for %s not found in %s\n", outputName, workspaceName)
283-
}
284-
285-
// findTfcWorkspace looks for a workspace by name in two different Terraform Cloud accounts and returns
286-
// the workspace ID and an API client for the account where the workspace was found
287-
func (d *DnsCommand) findTfcWorkspace(ctx context.Context, workspaceName string) (id string, client *tfe.Client, err error) {
288-
config := &tfe.Config{
289-
Token: d.tfcToken,
290-
RetryServerErrors: true,
291-
}
292-
293-
client, err = tfe.NewClient(config)
294-
if err != nil {
295-
err = fmt.Errorf("error creating Terraform client: %s", err)
296-
return
297-
}
298-
299-
w, err := client.Workspaces.Read(ctx, d.tfcOrg, workspaceName)
300-
if err == nil {
301-
id = w.ID
302-
return
303-
}
304-
305-
if d.tfcTokenAlt == "" {
306-
err = fmt.Errorf("error reading Terraform workspace %s: %s", workspaceName, err)
307-
return
308-
}
309-
310-
fmt.Printf("Workspace %s not found using %s, trying %s\n", workspaceName, flags.TfcToken, flags.TfcTokenAlternate)
311-
312-
config.Token = d.tfcTokenAlt
313-
client, err = tfe.NewClient(config)
314-
if err != nil {
315-
err = fmt.Errorf("error creating alternate Terraform client: %s", err)
316-
return
317-
}
318-
319-
w, err = client.Workspaces.Read(ctx, d.tfcOrgAlt, workspaceName)
320-
if err != nil {
321-
err = fmt.Errorf("error reading Terraform workspace %s using %s: %s", workspaceName, flags.TfcTokenAlternate, err)
322-
return
323-
}
324-
325-
id = w.ID
326-
return
327-
}

cmd/cli/multiregion/multiregion.go

+2-15
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ func SetupMultiregionCmd(parentCommand *cobra.Command) {
3333
flags.NewStringFlag(multiregionCmd, flags.Env, "", envProd, "Execution environment")
3434
flags.NewStringFlag(multiregionCmd, flags.Region2, "", "", "Secondary AWS region")
3535
flags.NewStringFlag(multiregionCmd, flags.TfcToken, "", "", "Token for Terraform Cloud authentication")
36-
flags.NewStringFlag(multiregionCmd, flags.OrgAlternate, "", "", "Alternate Terraform Cloud organization")
37-
flags.NewStringFlag(multiregionCmd, flags.TfcTokenAlternate, "", "", "Alternate token for Terraform Cloud")
3836
}
3937

4038
func outputFlagError(cmd *cobra.Command, err error) {
@@ -46,11 +44,10 @@ type PersistentFlags struct {
4644
env string
4745
idp string
4846
org string
49-
orgAlt string
5047
readOnlyMode bool
48+
region string
5149
secondaryRegion string
5250
tfcToken string
53-
tfcTokenAlt string
5451
}
5552

5653
func getPersistentFlags() PersistentFlags {
@@ -59,19 +56,9 @@ func getPersistentFlags() PersistentFlags {
5956
idp: getRequiredParam(flags.Idp),
6057
org: getRequiredParam(flags.Org),
6158
tfcToken: getRequiredParam(flags.TfcToken),
59+
region: getRequiredParam(flags.Region),
6260
secondaryRegion: getRequiredParam(flags.Region2),
6361
readOnlyMode: viper.GetBool(flags.ReadOnlyMode),
64-
tfcTokenAlt: getOption(flags.TfcTokenAlternate, ""),
65-
orgAlt: getOption(flags.OrgAlternate, viper.GetString(flags.OrgAlternate)),
66-
}
67-
68-
if pFlags.orgAlt != "" && pFlags.tfcTokenAlt == "" {
69-
log.Fatalf("%[1]s was specified without %[2]s. Please include %[2]s or remove %[1]s.",
70-
flags.OrgAlternate, flags.TfcTokenAlternate)
71-
}
72-
73-
if pFlags.orgAlt == "" {
74-
pFlags.orgAlt = pFlags.org
7562
}
7663

7764
return pFlags

go.mod

-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ go 1.20
66

77
require (
88
github.com/cloudflare/cloudflare-go v0.69.0
9-
github.com/hashicorp/go-tfe v1.31.0
109
github.com/silinternational/tfc-ops/v3 v3.5.0
1110
github.com/spf13/cobra v1.7.0
1211
github.com/spf13/viper v1.16.0
@@ -18,10 +17,7 @@ require (
1817
github.com/google/go-querystring v1.1.0 // indirect
1918
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
2019
github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
21-
github.com/hashicorp/go-slug v0.12.0 // indirect
22-
github.com/hashicorp/go-version v1.6.0 // indirect
2320
github.com/hashicorp/hcl v1.0.0 // indirect
24-
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d // indirect
2521
github.com/inconshreveable/mousetrap v1.1.0 // indirect
2622
github.com/magiconair/properties v1.8.7 // indirect
2723
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -32,7 +28,6 @@ require (
3228
github.com/spf13/pflag v1.0.5 // indirect
3329
github.com/subosito/gotenv v1.4.2 // indirect
3430
golang.org/x/net v0.10.0 // indirect
35-
golang.org/x/sync v0.3.0 // indirect
3631
golang.org/x/sys v0.9.0 // indirect
3732
golang.org/x/text v0.10.0 // indirect
3833
golang.org/x/time v0.3.0 // indirect

go.sum

-11
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,10 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
130130
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
131131
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
132132
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
133-
github.com/hashicorp/go-slug v0.12.0 h1:y1ArGp5RFF85uvD8nq5VZug/bup/kGN5Ft4xFOQ5GPM=
134-
github.com/hashicorp/go-slug v0.12.0/go.mod h1:JZVtycnZZbiJ4oxpJ/zfhyfBD8XxT4f0uOSyjNLCqFY=
135-
github.com/hashicorp/go-tfe v1.31.0 h1:R1CokrAVBHxrsvRw1vKes7RQxTRTWcula7gjQK7Jfsk=
136-
github.com/hashicorp/go-tfe v1.31.0/go.mod h1:vcfy2u52JQ4sYLFi941qcQXQYfUq2RjEW466tZ+m97Y=
137-
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
138-
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
139-
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
140133
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
141134
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
142135
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
143136
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
144-
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d h1:9ARUJJ1VVynB176G1HCwleORqCaXm/Vx0uUi0dL26I0=
145-
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik=
146137
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
147138
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
148139
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -302,8 +293,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
302293
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
303294
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
304295
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
305-
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
306-
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
307296
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
308297
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
309298
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

0 commit comments

Comments
 (0)