Skip to content

Commit 19700d7

Browse files
authored
Add support for Multiple Custom Domains (#1240)
* ACUL: Remomve unreleased screens in R6 * lint * lint * Add changelog for v1.14.1 * Add support for Multiple Custom Domains * Updated * tidy * Updated test * Updated domain name * updating test case formatting * Updated go files * updated example * Updated circl to 1.6.1 * Bumped go-auth0
1 parent 489abd0 commit 19700d7

9 files changed

Lines changed: 145 additions & 40 deletions

File tree

docs/auth0_domains_create.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ auth0 domains create [flags]
2222
auth0 domains create
2323
auth0 domains create --domain <domain-name>
2424
auth0 domains create --domain <domain-name> --policy recommended
25+
auth0 domains create --domain <domain-name> --policy recommended --metadata '{"key1":"value1","key2":"value2"}'
2526
auth0 domains create --domain <domain-name> --policy recommended --type auth0
2627
auth0 domains create --domain <domain-name> --policy recommended --type auth0 --ip-header "cf-connecting-ip"
2728
auth0 domains create -d <domain-name> -p recommended -t auth0 -i "cf-connecting-ip" --json
@@ -34,9 +35,10 @@ auth0 domains create [flags]
3435
-d, --domain string Domain name.
3536
-i, --ip-header string The HTTP header to fetch the client's IP address.
3637
--json Output in json format.
38+
-m, --metadata string The Custom Domain Metadata, formatted as JSON.
3739
-p, --policy string The TLS version policy. Can be either 'compatible' or 'recommended'.
3840
-t, --type string Custom domain provisioning type. Must be 'auth0' for Auth0-managed certs or 'self' for self-managed certs.
39-
-v, --verification string Custom domain verification method. Must be 'txt'.
41+
-v, --verification string *DEPRECATED* Custom domain verification method. Must be 'txt'.
4042
```
4143

4244

docs/auth0_domains_update.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ auth0 domains update [flags]
2222
auth0 domains update
2323
auth0 domains update <domain-id> --policy compatible
2424
auth0 domains update <domain-id> --policy compatible --ip-header "cf-connecting-ip"
25+
auth0 domains update <domain-id> --metadata '{"key1":"value1","key2":null}'
2526
auth0 domains update <domain-id> -p compatible -i "cf-connecting-ip" --json
2627
```
2728

@@ -31,6 +32,7 @@ auth0 domains update [flags]
3132
```
3233
-i, --ip-header string The HTTP header to fetch the client's IP address.
3334
--json Output in json format.
35+
-m, --metadata string The Custom Domain Metadata, formatted as JSON.
3436
-p, --policy string The TLS version policy. Can be either 'compatible' or 'recommended'.
3537
```
3638

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/AlecAivazis/survey/v2 v2.3.7
77
github.com/PuerkitoBio/rehttp v1.4.0
88
github.com/atotto/clipboard v0.1.4
9-
github.com/auth0/go-auth0 v1.24.0
9+
github.com/auth0/go-auth0 v1.25.0
1010
github.com/briandowns/spinner v1.23.2
1111
github.com/charmbracelet/glamour v0.10.0
1212
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
2222
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
2323
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
2424
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
25-
github.com/auth0/go-auth0 v1.24.0 h1:9H3Qv+mAbvv90OLab2pd2ktn7SFdQN86xY9d6niOtd0=
26-
github.com/auth0/go-auth0 v1.24.0/go.mod h1:g9S/4ImupKFx1gSLqeQO0v1yV91Oo5J5bYobLCAL+J4=
25+
github.com/auth0/go-auth0 v1.25.0 h1:fNlbDL8CPA+w3mfuuGD12cHjtEK/EDLJAc20xrL1+Eg=
26+
github.com/auth0/go-auth0 v1.25.0/go.mod h1:g9S/4ImupKFx1gSLqeQO0v1yV91Oo5J5bYobLCAL+J4=
2727
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48=
2828
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA=
2929
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=

internal/auth0/custom_domain.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ type CustomDomainAPI interface {
2626

2727
// List all custom domains.
2828
List(ctx context.Context, opts ...management.RequestOption) (c []*management.CustomDomain, err error)
29+
30+
// ListWithPagination lists all custom domains with support for pagination.
31+
ListWithPagination(ctx context.Context, opts ...management.RequestOption) (c *management.CustomDomainList, err error)
2932
}

internal/auth0/mock/custom_domain_mock.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/cli/custom_domains.go

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"context"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"net/url"
@@ -47,7 +48,7 @@ var (
4748
Name: "Verification Method",
4849
LongForm: "verification",
4950
ShortForm: "v",
50-
Help: "Custom domain verification method. Must be 'txt'.",
51+
Help: "*DEPRECATED* Custom domain verification method. Must be 'txt'.",
5152
}
5253

5354
customDomainPolicy = Flag{
@@ -66,6 +67,14 @@ var (
6667
AlwaysPrompt: true,
6768
}
6869

70+
customDomainMetadata = Flag{
71+
Name: "Domain Metadata",
72+
LongForm: "metadata",
73+
ShortForm: "m",
74+
Help: "The Custom Domain Metadata, formatted as JSON.",
75+
AlwaysPrompt: true,
76+
}
77+
6978
customDomainPolicyOptions = []string{
7079
customDomainTLSPolicyRecommended,
7180
customDomainTLSPolicyCompatible,
@@ -177,6 +186,7 @@ func createCustomDomainCmd(cli *cli) *cobra.Command {
177186
VerificationMethod string
178187
TLSPolicy string
179188
CustomClientIPHeader string
189+
DomainMetadata string
180190
}
181191

182192
cmd := &cobra.Command{
@@ -190,13 +200,21 @@ func createCustomDomainCmd(cli *cli) *cobra.Command {
190200
Example: ` auth0 domains create
191201
auth0 domains create --domain <domain-name>
192202
auth0 domains create --domain <domain-name> --policy recommended
203+
auth0 domains create --domain <domain-name> --policy recommended --metadata '{"key1":"value1","key2":"value2"}'
193204
auth0 domains create --domain <domain-name> --policy recommended --type auth0
194205
auth0 domains create --domain <domain-name> --policy recommended --type auth0 --ip-header "cf-connecting-ip"
195206
auth0 domains create -d <domain-name> -p recommended -t auth0 -i "cf-connecting-ip" --json`,
196207
RunE: func(cmd *cobra.Command, args []string) error {
197208
if err := customDomainDomain.Ask(cmd, &inputs.Domain, nil); err != nil {
198209
return err
199210
}
211+
if err := customDomainPolicy.Select(cmd, &inputs.TLSPolicy, customDomainPolicyOptions, auth0.String(customDomainTLSPolicyRecommended)); err != nil {
212+
return err
213+
}
214+
215+
if err := customDomainMetadata.Ask(cmd, &inputs.DomainMetadata, nil); err != nil {
216+
return err
217+
}
200218

201219
customDomain := &management.CustomDomain{
202220
Domain: &inputs.Domain,
@@ -208,10 +226,6 @@ func createCustomDomainCmd(cli *cli) *cobra.Command {
208226
customDomain.Type = auth0.String(customDomainProvisioningTypeAuth0)
209227
}
210228

211-
if inputs.VerificationMethod != "" {
212-
customDomain.VerificationMethod = apiVerificationMethodFor(inputs.VerificationMethod)
213-
}
214-
215229
if inputs.TLSPolicy != "" {
216230
customDomain.TLSPolicy = apiTLSPolicyFor(inputs.TLSPolicy)
217231
}
@@ -220,6 +234,14 @@ func createCustomDomainCmd(cli *cli) *cobra.Command {
220234
customDomain.CustomClientIPHeader = &inputs.CustomClientIPHeader
221235
}
222236

237+
if inputs.DomainMetadata != "" {
238+
var metadata map[string]interface{}
239+
if err := json.Unmarshal([]byte(inputs.DomainMetadata), &metadata); err != nil {
240+
return fmt.Errorf("invalid JSON for metadata: %w", err)
241+
}
242+
customDomain.DomainMetadata = &metadata
243+
}
244+
223245
if err := ansi.Waiting(func() error {
224246
return cli.api.CustomDomain.Create(cmd.Context(), customDomain)
225247
}); err != nil {
@@ -238,6 +260,7 @@ func createCustomDomainCmd(cli *cli) *cobra.Command {
238260
customDomainVerification.RegisterString(cmd, &inputs.VerificationMethod, "")
239261
customDomainPolicy.RegisterString(cmd, &inputs.TLSPolicy, "")
240262
customDomainIPHeader.RegisterString(cmd, &inputs.CustomClientIPHeader, "")
263+
customDomainMetadata.RegisterString(cmd, &inputs.DomainMetadata, "")
241264

242265
return cmd
243266
}
@@ -247,6 +270,7 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command {
247270
ID string
248271
TLSPolicy string
249272
CustomClientIPHeader string
273+
DomainMetadata string
250274
}
251275

252276
cmd := &cobra.Command{
@@ -260,7 +284,9 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command {
260284
Example: ` auth0 domains update
261285
auth0 domains update <domain-id> --policy compatible
262286
auth0 domains update <domain-id> --policy compatible --ip-header "cf-connecting-ip"
263-
auth0 domains update <domain-id> -p compatible -i "cf-connecting-ip" --json`,
287+
auth0 domains update <domain-id> --metadata '{"key1":"value1","key2":null}'
288+
auth0 domains update <domain-id> -p compatible -i "cf-connecting-ip" --json
289+
`,
264290
RunE: func(cmd *cobra.Command, args []string) error {
265291
var current *management.CustomDomain
266292

@@ -287,6 +313,10 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command {
287313
return err
288314
}
289315

316+
if err := customDomainMetadata.AskU(cmd, &inputs.DomainMetadata, nil); err != nil {
317+
return err
318+
}
319+
290320
// Start with an empty custom domain object. We'll conditionally
291321
// hydrate it based on the provided parameters since
292322
// we'll do PATCH semantics.
@@ -300,12 +330,29 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command {
300330
c.CustomClientIPHeader = &inputs.CustomClientIPHeader
301331
}
302332

333+
if inputs.DomainMetadata != "" {
334+
var metadata map[string]interface{}
335+
if err := json.Unmarshal([]byte(inputs.DomainMetadata), &metadata); err != nil {
336+
return fmt.Errorf("invalid JSON for metadata: %w", err)
337+
}
338+
c.DomainMetadata = &metadata
339+
}
340+
303341
if err := ansi.Waiting(func() error {
304342
return cli.api.CustomDomain.Update(cmd.Context(), inputs.ID, c)
305343
}); err != nil {
306344
return fmt.Errorf("failed to update custom domain: %w", err)
307345
}
308346

347+
// AFTER the API call: clean nil values from the map for clean rendering.
348+
if c.DomainMetadata != nil {
349+
for k, v := range *c.DomainMetadata {
350+
if v == nil {
351+
delete(*c.DomainMetadata, k)
352+
}
353+
}
354+
}
355+
309356
cli.renderer.CustomDomainUpdate(c)
310357

311358
return nil
@@ -314,6 +361,7 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command {
314361

315362
customDomainPolicy.RegisterStringU(cmd, &inputs.TLSPolicy, "")
316363
customDomainIPHeader.RegisterStringU(cmd, &inputs.CustomClientIPHeader, "")
364+
customDomainMetadata.RegisterString(cmd, &inputs.DomainMetadata, "")
317365

318366
cmd.Flags().BoolVar(&cli.json, "json", false, "Output in json format.")
319367

internal/display/custom_domain.go

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,22 @@ import (
77
)
88

99
type customDomainView struct {
10-
ID string
11-
Domain string
12-
Status string
13-
Primary string
14-
ProvisioningType string
15-
VerificationMethod string
16-
VerificationRecord string
17-
VerificationDomain string
18-
TLSPolicy string
19-
CustomClientIPHeader string
20-
raw interface{}
10+
ID string
11+
Domain string
12+
Status string
13+
Primary string
14+
ProvisioningType string
15+
VerificationMethod string
16+
VerificationRecord string
17+
VerificationDomain string
18+
TLSPolicy string
19+
CustomClientIPHeader string
20+
DomainMetadata string
21+
CertificateStatus string
22+
CertificateErrorMsg string
23+
CertificateAuthority string
24+
CertificateRenewsBefore string
25+
raw interface{}
2126
}
2227

2328
func (v *customDomainView) AsTableHeader() []string {
@@ -65,7 +70,21 @@ func (v *customDomainView) KeyValues() [][]string {
6570
if v.CustomClientIPHeader != "" {
6671
keyValues = append(keyValues, []string{"CUSTOM CLIENT IP HEADER", v.CustomClientIPHeader})
6772
}
68-
73+
if v.DomainMetadata != "" {
74+
keyValues = append(keyValues, []string{"DOMAIN METADATA", v.DomainMetadata})
75+
}
76+
if v.CertificateStatus != "" {
77+
keyValues = append(keyValues, []string{ansi.Yellow(ansi.Bold("CERTIFICATE STATUS")), ansi.Yellow(ansi.Bold(v.CertificateStatus))})
78+
}
79+
if v.CertificateErrorMsg != "" {
80+
keyValues = append(keyValues, []string{ansi.Yellow(ansi.Bold("CERTIFICATE ERROR MSG")), ansi.Yellow(ansi.Bold(v.CertificateErrorMsg))})
81+
}
82+
if v.CertificateAuthority != "" {
83+
keyValues = append(keyValues, []string{ansi.Yellow(ansi.Bold("CERTIFICATE AUTHORITY")), ansi.Yellow(ansi.Bold(v.CertificateAuthority))})
84+
}
85+
if v.CertificateRenewsBefore != "" {
86+
keyValues = append(keyValues, []string{ansi.Yellow(ansi.Bold("CERTIFICATE RENEWS BEFORE")), ansi.Yellow(ansi.Bold(v.CertificateRenewsBefore))})
87+
}
6988
return keyValues
7089
}
7190

@@ -107,15 +126,24 @@ func (r *Renderer) CustomDomainUpdate(customDomain *management.CustomDomain) {
107126
}
108127

109128
func makeCustomDomainView(customDomain *management.CustomDomain) *customDomainView {
129+
metadata, err := toJSONString(customDomain.GetDomainMetadata())
130+
if err != nil {
131+
return nil
132+
}
133+
110134
view := &customDomainView{
111-
ID: ansi.Faint(customDomain.GetID()),
112-
Domain: customDomain.GetDomain(),
113-
Status: customDomainStatusColor(customDomain.GetStatus()),
114-
Primary: boolean(customDomain.GetPrimary()),
115-
ProvisioningType: customDomain.GetType(),
116-
TLSPolicy: customDomain.GetTLSPolicy(),
117-
CustomClientIPHeader: customDomain.GetCustomClientIPHeader(),
118-
raw: customDomain,
135+
ID: ansi.Faint(customDomain.GetID()),
136+
Domain: customDomain.GetDomain(),
137+
Status: customDomainStatusColor(customDomain.GetStatus()),
138+
Primary: boolean(customDomain.GetPrimary()),
139+
ProvisioningType: customDomain.GetType(),
140+
TLSPolicy: customDomain.GetTLSPolicy(),
141+
CustomClientIPHeader: customDomain.GetCustomClientIPHeader(),
142+
DomainMetadata: metadata,
143+
CertificateStatus: customDomain.GetCertificate().GetStatus(),
144+
CertificateAuthority: customDomain.GetCertificate().GetCertificateAuthority(),
145+
CertificateRenewsBefore: customDomain.GetCertificate().GetRenewsBefore(),
146+
raw: customDomain,
119147
}
120148

121149
if len(customDomain.GetVerification().Methods) > 0 {

test/integration/custom-domains-test-cases.yaml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ tests:
1818
exactly: "[]"
1919

2020
003 - create domain with minimal flags:
21-
command: auth0 domains create --domain "auth0-cli-integration-tests.com" --no-input
21+
command: auth0 domains create --domain "auth0-cli-integration-tests.com" --metadata '{"key1":"value1","key2":"value2"}' --no-input
2222
exit-code: 0
2323
stdout:
2424
contains:
25-
- "ID cd_"
26-
- "DOMAIN auth0-cli-integration-tests.com"
27-
- "STATUS pending_verification"
28-
- "PROVISIONING TYPE auth0_managed_certs"
25+
- ID cd_
26+
- DOMAIN auth0-cli-integration-tests.com
27+
- STATUS pending_verification
28+
- PROVISIONING TYPE auth0_managed_certs
29+
- DOMAIN METADATA {"key1":"value1","key2":"value2"}
2930

3031
004 - unsuccessfully create domain with same name:
3132
command: auth0 domains create --domain "auth0-cli-integration-tests.com" --no-input
@@ -45,14 +46,15 @@ tests:
4546
- "PROVISIONING TYPE auth0_managed_certs"
4647

4748
006 - update domain minimal flags:
48-
command: auth0 domains update $(./test/integration/scripts/get-custom-domain-id.sh) --no-input
49+
command: auth0 domains update $(./test/integration/scripts/get-custom-domain-id.sh) --metadata '{"key1":"value1","key2":null}' --no-input
4950
exit-code: 0
5051
stdout:
5152
contains:
52-
- "ID cd_"
53-
- "DOMAIN auth0-cli-integration-tests.com"
54-
- "STATUS pending_verification"
55-
- "PROVISIONING TYPE auth0_managed_certs"
53+
- ID cd_
54+
- DOMAIN auth0-cli-integration-tests.com
55+
- STATUS pending_verification
56+
- PROVISIONING TYPE auth0_managed_certs
57+
- DOMAIN METADATA {"key1":"value1"}
5658

5759
007 - update domain maximal flags:
5860
command: auth0 domains update $(./test/integration/scripts/get-custom-domain-id.sh) --policy recommended --no-input

0 commit comments

Comments
 (0)