Skip to content

Commit 1f3fd79

Browse files
authored
fix: add support for AuthConfig Cognito (#2029)
Signed-off-by: Kevin McDermott <kevin.mcdermott@suse.com>
1 parent f9c7a99 commit 1f3fd79

12 files changed

Lines changed: 585 additions & 74 deletions

aspell_custom.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ backport
3232
GKE
3333
PDB
3434
PC
35+
AuthConfig
36+
Cognito

rancher2/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,8 @@ func getAuthConfigObject(kind string) (interface{}, error) {
12251225
return &managementClient.KeyCloakConfig{}, nil
12261226
case managementClient.GenericOIDCConfigType:
12271227
return &managementClient.GenericOIDCConfig{}, nil
1228+
case managementClient.CognitoConfigType:
1229+
return &managementClient.CognitoConfig{}, nil
12281230
case managementClient.OIDCConfigType:
12291231
return &managementClient.OIDCConfig{}, nil
12301232
case managementClient.OKTAConfigType:

rancher2/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ func Provider() terraform.ResourceProvider {
117117
"rancher2_auth_config_keycloak": resourceRancher2AuthConfigKeyCloak(),
118118
"rancher2_auth_config_okta": resourceRancher2AuthConfigOKTA(),
119119
"rancher2_auth_config_generic_oidc": resourceRancher2AuthConfigGenericOIDC(),
120+
"rancher2_auth_config_cognito": resourceRancher2AuthConfigCognito(),
120121
"rancher2_auth_config_openldap": resourceRancher2AuthConfigOpenLdap(),
121122
"rancher2_auth_config_ping": resourceRancher2AuthConfigPing(),
122123
"rancher2_bootstrap": resourceRancher2Bootstrap(),
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package rancher2
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
8+
managementClient "github.com/rancher/rancher/pkg/client/generated/management/v3"
9+
)
10+
11+
func resourceRancher2AuthConfigCognito() *schema.Resource {
12+
return &schema.Resource{
13+
Create: resourceRancher2AuthConfigCognitoCreate,
14+
Read: resourceRancher2AuthConfigCognitoRead,
15+
Update: resourceRancher2AuthConfigCognitoUpdate,
16+
Delete: resourceRancher2AuthConfigCognitoDelete,
17+
18+
Schema: authConfigCognitoFields(),
19+
}
20+
}
21+
22+
func resourceRancher2AuthConfigCognitoCreate(d *schema.ResourceData, meta interface{}) error {
23+
client, err := meta.(*Config).ManagementClient()
24+
if err != nil {
25+
return err
26+
}
27+
28+
auth, err := client.AuthConfig.ByID(AuthConfigCognitoName)
29+
if err != nil {
30+
return fmt.Errorf("[ERROR] Failed to get Auth Config %s: %s", AuthConfigCognitoName, err)
31+
}
32+
33+
log.Printf("[INFO] Creating Auth Config %s", AuthConfigCognitoName)
34+
35+
authOIDC, err := expandAuthConfigCognito(d)
36+
if err != nil {
37+
return fmt.Errorf("[ERROR] Failed expanding Auth Config %s: %s", AuthConfigCognitoName, err)
38+
}
39+
40+
// Checking if other auth config is enabled
41+
if authOIDC.Enabled {
42+
err = meta.(*Config).CheckAuthConfigEnabled(AuthConfigCognitoName)
43+
if err != nil {
44+
return fmt.Errorf("[ERROR] Checking to enable Auth Config %s: %s", AuthConfigCognitoName, err)
45+
}
46+
}
47+
48+
newAuth := &managementClient.CognitoConfig{}
49+
err = meta.(*Config).UpdateAuthConfig(auth.Links["self"], authOIDC, newAuth)
50+
if err != nil {
51+
return fmt.Errorf("[ERROR] Updating Auth Config %s: %s", AuthConfigCognitoName, err)
52+
}
53+
54+
return resourceRancher2AuthConfigCognitoRead(d, meta)
55+
}
56+
57+
func resourceRancher2AuthConfigCognitoRead(d *schema.ResourceData, meta interface{}) error {
58+
log.Printf("[INFO] Refreshing Auth Config %s", AuthConfigCognitoName)
59+
client, err := meta.(*Config).ManagementClient()
60+
if err != nil {
61+
return err
62+
}
63+
64+
auth, err := client.AuthConfig.ByID(AuthConfigCognitoName)
65+
if err != nil {
66+
if IsNotFound(err) {
67+
log.Printf("[INFO] Auth Config %s not found.", AuthConfigCognitoName)
68+
d.SetId("")
69+
return nil
70+
}
71+
return err
72+
}
73+
74+
authOIDC, err := meta.(*Config).GetAuthConfig(auth)
75+
if err != nil {
76+
return err
77+
}
78+
79+
err = flattenAuthConfigCognito(d, authOIDC.(*managementClient.CognitoConfig))
80+
if err != nil {
81+
return err
82+
}
83+
84+
return nil
85+
}
86+
87+
func resourceRancher2AuthConfigCognitoUpdate(d *schema.ResourceData, meta interface{}) error {
88+
log.Printf("[INFO] Updating Auth Config %s", AuthConfigCognitoName)
89+
return resourceRancher2AuthConfigCognitoCreate(d, meta)
90+
}
91+
92+
func resourceRancher2AuthConfigCognitoDelete(d *schema.ResourceData, meta interface{}) error {
93+
log.Printf("[INFO] Disabling Auth Config %s", AuthConfigCognitoName)
94+
95+
client, err := meta.(*Config).ManagementClient()
96+
if err != nil {
97+
return err
98+
}
99+
100+
auth, err := client.AuthConfig.ByID(AuthConfigCognitoName)
101+
if err != nil {
102+
if IsNotFound(err) {
103+
log.Printf("[INFO] Auth Config %s not found.", AuthConfigCognitoName)
104+
d.SetId("")
105+
return nil
106+
}
107+
return err
108+
}
109+
110+
if auth.Enabled == true {
111+
err = client.Post(auth.Actions["disable"], nil, nil)
112+
if err != nil {
113+
return fmt.Errorf("[ERROR] Disabling Auth Config %s: %s", AuthConfigCognitoName, err)
114+
}
115+
}
116+
117+
d.SetId("")
118+
return nil
119+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package rancher2
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
5+
)
6+
7+
const AuthConfigCognitoName = "cognito"
8+
9+
//Schemas
10+
11+
func authConfigCognitoFields() map[string]*schema.Schema {
12+
fields := oidcSchemaFields()
13+
14+
fields["name_claim"].Default = "cognito:username"
15+
16+
// Terraform doesn't allow defaults for Computed fields.
17+
//
18+
// It's not clear why this field is Computed in the Schema, but we'll set it
19+
// to false so we can provide a default.
20+
fields["groups_field"].Computed = false
21+
fields["groups_field"].Default = "cognito:groups"
22+
23+
return fields
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package rancher2
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
7+
)
8+
9+
func TestAuthConfigCognitoResourceDefaults(t *testing.T) {
10+
r := resourceRancher2AuthConfigCognito()
11+
d := schema.TestResourceDataRaw(t, r.Schema, map[string]any{
12+
"client_id": "client-id",
13+
"client_secret": "client-secret",
14+
"issuer": "https://issuer.example.com",
15+
"rancher_url": "https://rancher.example.com/verify-auth",
16+
})
17+
18+
if got := d.Get("name_claim"); got != "cognito:username" {
19+
t.Fatalf("unexpected default for name_claim: got %v, want %q", got, "cognito:username")
20+
}
21+
22+
if got := d.Get("group_search_enabled"); got != false {
23+
t.Fatalf("unexpected default for group_search_enabled: got %v, want %v", got, false)
24+
}
25+
}

rancher2/schema_auth_config_generic_oidc.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package rancher2
22

33
import (
4+
"maps"
5+
46
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
7+
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
58
)
69

710
const AuthConfigGenericOIDCName = "genericoidc"
811

912
//Schemas
1013

1114
func authConfigGenericOIDCFields() map[string]*schema.Schema {
15+
return oidcSchemaFields()
16+
}
17+
18+
// This is used by the Cognito and Generic OIDC providers.
19+
func oidcSchemaFields() map[string]*schema.Schema {
1220
s := map[string]*schema.Schema{
1321
"client_id": {
1422
Type: schema.TypeString,
@@ -88,11 +96,37 @@ func authConfigGenericOIDCFields() map[string]*schema.Schema {
8896
StateFunc: TrimSpace,
8997
Description: "A PEM-encoded private key for the OIDC provider.",
9098
},
99+
"name_claim": {
100+
Type: schema.TypeString,
101+
Optional: true,
102+
StateFunc: TrimSpace,
103+
Description: "The OIDC Claim to use for the user name.",
104+
},
105+
"email_claim": {
106+
Type: schema.TypeString,
107+
Optional: true,
108+
StateFunc: TrimSpace,
109+
Description: "The OIDC Claim to use for the user email.",
110+
},
111+
"logout_all_enabled": {
112+
Type: schema.TypeBool,
113+
Optional: true,
114+
Description: "Allow the user to choose whether or not to logout of their session with the IdP.",
115+
},
116+
"logout_all_forced": {
117+
Type: schema.TypeBool,
118+
Optional: true,
119+
Description: "Force the user to logout of their session with the IdP.",
120+
},
121+
"end_session_endpoint": {
122+
Type: schema.TypeString,
123+
Optional: true,
124+
ValidateFunc: validation.IsURLWithHTTPS,
125+
Description: "The provider specific URL used for logging a user out of their session.",
126+
},
91127
}
92128

93-
for k, v := range authConfigFields() {
94-
s[k] = v
95-
}
129+
maps.Copy(s, authConfigFields())
96130

97131
return s
98132
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package rancher2
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/terraform"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestAuthConfigGenericOIDCResourceValidateNoData(t *testing.T) {
12+
r := resourceRancher2AuthConfigGenericOIDC()
13+
d := terraform.NewResourceConfigRaw(map[string]any{})
14+
warns, errs := r.Validate(d)
15+
16+
assert.Empty(t, warns)
17+
18+
assert.Len(t, errs, 4)
19+
joined := errors.Join(errs...)
20+
assert.ErrorContains(t, joined, "\"issuer\": required field is not set")
21+
assert.ErrorContains(t, joined, "\"client_id\": required field is not set")
22+
assert.ErrorContains(t, joined, "\"client_secret\": required field is not set")
23+
assert.ErrorContains(t, joined, "\"rancher_url\": required field is not set")
24+
}
25+
26+
func TestAuthConfigGenericOIDCResourceEndSessionEndpointValidation(t *testing.T) {
27+
r := resourceRancher2AuthConfigGenericOIDC()
28+
d := terraform.NewResourceConfigRaw(map[string]any{
29+
"client_id": "client-id",
30+
"client_secret": "client-secret",
31+
"issuer": "https://issuer.example.com",
32+
"rancher_url": "https://rancher.example.com/verify-auth",
33+
"end_session_endpoint": "test",
34+
})
35+
warns, errs := r.Validate(d)
36+
37+
assert.Empty(t, warns)
38+
assert.ErrorContains(t, errors.Join(errs...), `expected "end_session_endpoint" to have a host`)
39+
}

0 commit comments

Comments
 (0)