Skip to content

Commit fe005b0

Browse files
committed
feat(iam): datasource to query service-accounts
Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>
1 parent 8bbc3e0 commit fe005b0

17 files changed

Lines changed: 728 additions & 106 deletions
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "stackit_service_accounts Data Source - stackit"
4+
subcategory: ""
5+
description: |-
6+
Service accounts plural data source schema. Returns a list of all service accounts in a project, optionally filtered.
7+
---
8+
9+
# stackit_service_accounts (Data Source)
10+
11+
Service accounts plural data source schema. Returns a list of all service accounts in a project, optionally filtered.
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "stackit_service_accounts" "all_sas" {
17+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
18+
}
19+
20+
data "stackit_service_accounts" "sas_default_suffix" {
21+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
22+
email_suffix = "@sa.stackit.cloud"
23+
}
24+
25+
data "stackit_service_accounts" "sas_default_suffix_sort_asc" {
26+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
27+
email_suffix = "@sa.stackit.cloud"
28+
sort_ascending = true
29+
}
30+
31+
data "stackit_service_accounts" "sas_ske_regex" {
32+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
33+
email_regex = ".*@ske\\.sa\\.stackit\\.cloud$"
34+
}
35+
36+
data "stackit_service_accounts" "sas_ske_suffix" {
37+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
38+
email_suffix = "@ske.sa.stackit.cloud"
39+
}
40+
```
41+
42+
<!-- schema generated by tfplugindocs -->
43+
## Schema
44+
45+
### Required
46+
47+
- `project_id` (String) STACKIT project ID.
48+
49+
### Optional
50+
51+
- `email_regex` (String) Optional regular expression to filter service accounts by email.
52+
- `email_suffix` (String) Optional suffix to filter service accounts by email (e.g.,`@sa.stackit.cloud`, `@ske.sa.stackit.cloud`).
53+
- `sort_ascending` (Boolean) If set to `true`, service accounts are sorted in ascending lexicographical order by email. Defaults to `false` (descending).
54+
55+
### Read-Only
56+
57+
- `id` (String) Terraform's internal resource ID, structured as "`project_id`".
58+
- `items` (Attributes List) The list of service accounts matching the provided filters. (see [below for nested schema](#nestedatt--items))
59+
60+
<a id="nestedatt--items"></a>
61+
### Nested Schema for `items`
62+
63+
Read-Only:
64+
65+
- `email` (String) Email of the service account.
66+
- `name` (String) Name of the service account.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
data "stackit_service_accounts" "all_sas" {
2+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3+
}
4+
5+
data "stackit_service_accounts" "sas_default_suffix" {
6+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
7+
email_suffix = "@sa.stackit.cloud"
8+
}
9+
10+
data "stackit_service_accounts" "sas_default_suffix_sort_asc" {
11+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
12+
email_suffix = "@sa.stackit.cloud"
13+
sort_ascending = true
14+
}
15+
16+
data "stackit_service_accounts" "sas_ske_regex" {
17+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
18+
email_regex = ".*@ske\\.sa\\.stackit\\.cloud$"
19+
}
20+
21+
data "stackit_service_accounts" "sas_ske_suffix" {
22+
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
23+
email_suffix = "@ske.sa.stackit.cloud"
24+
}

stackit/internal/services/serviceaccount/account/datasource.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (r *serviceAccountDataSource) Read(ctx context.Context, req datasource.Read
140140
}
141141

142142
// Try to parse the name from the provided email address
143-
name, err := parseNameFromEmail(model.Email.ValueString())
143+
name, err := serviceaccountUtils.ParseNameFromEmail(model.Email.ValueString())
144144
if name != "" && err == nil {
145145
model.Name = types.StringValue(name)
146146
}

stackit/internal/services/serviceaccount/account/resource.go

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ func (r *serviceAccountResource) ImportState(ctx context.Context, req resource.I
280280
email := idParts[1]
281281

282282
// Attempt to parse the name from the email if valid.
283-
name, err := parseNameFromEmail(email)
283+
name, err := serviceaccountUtils.ParseNameFromEmail(email)
284284
if name != "" && err == nil {
285285
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), name)...)
286286
}
@@ -322,19 +322,3 @@ func mapFields(resp *serviceaccount.ServiceAccount, model *Model) error {
322322

323323
return nil
324324
}
325-
326-
// parseNameFromEmail extracts the name component from an email address.
327-
// The email format must be `name-<random7characters>@sa.stackit.cloud`.
328-
func parseNameFromEmail(email string) (string, error) {
329-
namePattern := `^([a-z][a-z0-9]*(?:-[a-z0-9]+)*)-\w{7}@sa\.stackit\.cloud$`
330-
re := regexp.MustCompile(namePattern)
331-
match := re.FindStringSubmatch(email)
332-
333-
// If a match is found, return the name component
334-
if len(match) > 1 {
335-
return match[1], nil
336-
}
337-
338-
// If no match is found, return an error
339-
return "", fmt.Errorf("unable to parse name from email")
340-
}

stackit/internal/services/serviceaccount/account/resource_test.go

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -123,39 +123,3 @@ func TestMapFields(t *testing.T) {
123123
})
124124
}
125125
}
126-
127-
func TestParseNameFromEmail(t *testing.T) {
128-
testCases := []struct {
129-
email string
130-
expected string
131-
shouldError bool
132-
}{
133-
{"test03-8565oq1@sa.stackit.cloud", "test03", false},
134-
{"import-test-vshp191@sa.stackit.cloud", "import-test", false},
135-
{"sa-test-01-acfj2s1@sa.stackit.cloud", "sa-test-01", false},
136-
{"invalid-email@sa.stackit.cloud", "", true},
137-
{"missingcode-@sa.stackit.cloud", "", true},
138-
{"nohyphen8565oq1@sa.stackit.cloud", "", true},
139-
{"eu01-qnmbwo1@unknown.stackit.cloud", "", true},
140-
{"eu01-qnmbwo1@ske.stackit.com", "", true},
141-
{"someotherformat@sa.stackit.cloud", "", true},
142-
}
143-
144-
for _, tc := range testCases {
145-
t.Run(tc.email, func(t *testing.T) {
146-
name, err := parseNameFromEmail(tc.email)
147-
if tc.shouldError {
148-
if err == nil {
149-
t.Errorf("expected an error for email: %s, but got none", tc.email)
150-
}
151-
} else {
152-
if err != nil {
153-
t.Errorf("did not expect an error for email: %s, but got: %v", tc.email, err)
154-
}
155-
if name != tc.expected {
156-
t.Errorf("expected name: %s, got: %s for email: %s", tc.expected, name, tc.email)
157-
}
158-
}
159-
})
160-
}
161-
}

0 commit comments

Comments
 (0)