-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Resources for Claims Mapping Policy Management #733
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
subcategory: "Policies" | ||
--- | ||
|
||
# Resource: claims_mapping_policy | ||
|
||
Manages a Claims Mapping Policy within Azure Active Directory. | ||
|
||
## API Permissions | ||
|
||
The following API permissions are required in order to use this resource. | ||
|
||
When authenticated with a service principal, this resource requires the following application roles: `Policy.ReadWrite.ApplicationConfiguration` | ||
|
||
When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
resource "azuread_claims_mapping_policy" "test" { | ||
definition = [ | ||
jsonencode( | ||
{ | ||
ClaimsMappingPolicy = { | ||
ClaimsSchema = [ | ||
{ | ||
ID = "employeeid" | ||
JwtClaimType = "name" | ||
SamlClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" | ||
Source = "user" | ||
}, | ||
{ | ||
ID = "tenantcountry" | ||
JwtClaimType = "country" | ||
SamlClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country" | ||
Source = "company" | ||
} | ||
] | ||
IncludeBasicClaimSet = "true" | ||
Version = 1 | ||
} | ||
} | ||
), | ||
] | ||
description = "hcl-created-policy" | ||
display_name = "hcl-create-policy" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `definition` - (Required) The claims mapping policy. This is a JSON formatted | ||
string, for which the [`jsonencode()` function](https://www.terraform.io/language/functions/jsonencode) | ||
can be used. | ||
* `description` - (Required) The description for this Claims Mapping Policy. | ||
* `display_name` - (Required) The friendly name for this Claims Mapping Policy. | ||
|
||
## Attributes Reference | ||
|
||
In addition to all arguments above, the following attributes are exported: | ||
|
||
* `id` - The ID of the Claims Mapping Policy. | ||
|
||
## Import | ||
|
||
Claims Mapping Policy can be imported using the `id`, e.g. | ||
|
||
```shell | ||
terraform import azuread_claims_mapping_policy.id 00000000-0000-0000-0000-000000000000 | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
|
||
--- | ||
subcategory: "Policies" | ||
--- | ||
|
||
# Resource: claims_mapping_policy_assignment | ||
|
||
Manages a Claims Mapping Policy Assignment within Azure Active Directory. | ||
|
||
## API Permissions | ||
|
||
The following API permissions are required in order to use this resource. | ||
|
||
When authenticated with a service principal, this resource requires the following application roles: `Policy.ReadWrite.ApplicationConfiguration` | ||
|
||
When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
resource "azuread_claims_mapping_policy_assignment" "app" { | ||
claims_mapping_policy_id = azuread_claims_mapping_policy.my_policy.id | ||
service_principal_id = azuread_service_principal.my_principal.id | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `claims_mapping_policy_id` - (Required) The `id` of the claims mapping policy to assign. | ||
* `service_principal_id` - (Required) The `id` of the service principal for the policy assignment. | ||
|
||
## Attributes Reference | ||
|
||
In addition to all arguments above, the following attributes are exported: | ||
|
||
* `id` - The ID of the Claims Mapping Policy Assignment. | ||
|
||
## Import | ||
|
||
Claims Mapping Policy can be imported using the `id`, in the form `service-principal-uuid/azuread_claims_mapping_policy/claims-mapping-policy-uuid`, e.g: | ||
|
||
```shell | ||
terraform import azuread_claims_mapping_policy_assignment.app 00000000-0000-0000-0000-000000000000/azuread_claims_mapping_policy/00000000-0000-0000-0000-000000000000 | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package parse | ||
|
||
import "fmt" | ||
|
||
type ClaimsMappingPolicyAssignmentId struct { | ||
ObjectSubResourceId | ||
ServicePolicyId string | ||
ClaimsMappingPolicyId string | ||
} | ||
|
||
func NewClaimsMappingPolicyAssignmentID(ServicePolicyId, ClaimsMappingPolicyId string) ClaimsMappingPolicyAssignmentId { | ||
return ClaimsMappingPolicyAssignmentId{ | ||
ObjectSubResourceId: NewObjectSubResourceID(ServicePolicyId, "azuread_claims_mapping_policy", ClaimsMappingPolicyId), | ||
ServicePolicyId: ServicePolicyId, | ||
ClaimsMappingPolicyId: ClaimsMappingPolicyId, | ||
} | ||
} | ||
|
||
func ClaimsMappingPolicyAssignmentID(idString string) (*ClaimsMappingPolicyAssignmentId, error) { | ||
id, err := ObjectSubResourceID(idString, "azuread_claims_mapping_policy") | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to parse azuread_claims_mapping_policy ID: %v", err) | ||
} | ||
|
||
return &ClaimsMappingPolicyAssignmentId{ | ||
ObjectSubResourceId: *id, | ||
ServicePolicyId: id.objectId, | ||
ClaimsMappingPolicyId: id.subId, | ||
}, nil | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,162 @@ | ||||||
package serviceprincipals | ||||||
|
||||||
import ( | ||||||
"context" | ||||||
"fmt" | ||||||
"log" | ||||||
"net/http" | ||||||
|
||||||
"github.com/hashicorp/go-uuid" | ||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||||||
"github.com/hashicorp/terraform-provider-azuread/internal/clients" | ||||||
"github.com/hashicorp/terraform-provider-azuread/internal/tf" | ||||||
"github.com/manicminer/hamilton/msgraph" | ||||||
"github.com/manicminer/hamilton/odata" | ||||||
) | ||||||
|
||||||
func servicePrincipalClaimsMappingPolicy() *schema.Resource { | ||||||
return &schema.Resource{ | ||||||
CreateContext: servicePrincipalClaimsMappingPolicyResourceCreate, | ||||||
ReadContext: servicePrincipalClaimsMappingPolicyResourceRead, | ||||||
UpdateContext: servicePrincipalClaimsMappingPolicyResourceUpdate, | ||||||
DeleteContext: servicePrincipalClaimsMappingPolicyResourceDelete, | ||||||
|
||||||
Importer: tf.ValidateResourceIDPriorToImport(func(id string) error { | ||||||
if _, err := uuid.ParseUUID(id); err != nil { | ||||||
return fmt.Errorf("specified ID (%q) is not valid: %s", id, err) | ||||||
} | ||||||
return nil | ||||||
}), | ||||||
|
||||||
Schema: map[string]*schema.Schema{ | ||||||
"id": { | ||||||
Description: "Unique identifier for this policy", | ||||||
Type: schema.TypeString, | ||||||
Computed: true, | ||||||
}, | ||||||
|
||||||
"definition": { | ||||||
Description: "A string collection containing a JSON string " + | ||||||
"that defines the rules and settings for this policy.", | ||||||
Type: schema.TypeList, | ||||||
Required: true, | ||||||
Elem: &schema.Schema{ | ||||||
Type: schema.TypeString, | ||||||
}, | ||||||
}, | ||||||
Comment on lines
+39
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As this is a list, does this mean that multiple policies can be specified? If not, can we collapse this into a singular string type. Also, the description for the property should match the description in the documentation (as we'll use the schema description in future to generate the documentation). |
||||||
|
||||||
"display_name": { | ||||||
Description: "Display name for this policy", | ||||||
Type: schema.TypeString, | ||||||
Required: true, | ||||||
}, | ||||||
|
||||||
"description": { | ||||||
Description: "Description for this policy", | ||||||
Optional: true, | ||||||
Type: schema.TypeString, | ||||||
Required: false, | ||||||
}, | ||||||
computeracer marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
}, | ||||||
} | ||||||
} | ||||||
|
||||||
func servicePrincipalClaimsMappingPolicyResourceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||||||
client := meta.(*clients.Client).ServicePrincipals.ClaimsMappingPolicyClient | ||||||
var definitions []string | ||||||
for _, v := range d.Get("definition").([]interface{}) { | ||||||
definitions = append(definitions, v.(string)) | ||||||
} | ||||||
|
||||||
displayName := d.Get("display_name").(string) | ||||||
|
||||||
claimsMappingPolicy := msgraph.ClaimsMappingPolicy{ | ||||||
Definition: &definitions, | ||||||
DisplayName: &displayName, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can use the
Suggested change
|
||||||
} | ||||||
policy, _, err := client.Create(ctx, claimsMappingPolicy) | ||||||
if err != nil { | ||||||
return tf.ErrorDiagF(err, "Could not create ClaimsMappingPolicy %q", displayName) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need to identify the resource in the error message, as Terraform will handle that for us
Suggested change
|
||||||
} | ||||||
|
||||||
if policy != nil { | ||||||
d.SetId(*policy.ID) | ||||||
} | ||||||
|
||||||
return servicePrincipalClaimsMappingPolicyResourceRead(ctx, d, meta) | ||||||
} | ||||||
|
||||||
func servicePrincipalClaimsMappingPolicyResourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||||||
client := meta.(*clients.Client).ServicePrincipals.ClaimsMappingPolicyClient | ||||||
objectId := d.Id() | ||||||
|
||||||
policy, status, err := client.Get(ctx, objectId, odata.Query{}) | ||||||
if err != nil { | ||||||
if status == http.StatusNotFound { | ||||||
log.Printf("[DEBUG] Claims Mapping Policy with Object ID %q was not found - removing from state!", objectId) | ||||||
d.SetId("") | ||||||
return nil | ||||||
} | ||||||
|
||||||
return tf.ErrorDiagF(err, "retrieving Claims Mapping Policy with object ID: %q", d.Id()) | ||||||
} | ||||||
|
||||||
tf.Set(d, "id", policy.ID) | ||||||
tf.Set(d, "definition", policy.Definition) | ||||||
tf.Set(d, "display_name", policy.DisplayName) | ||||||
|
||||||
return nil | ||||||
} | ||||||
|
||||||
func servicePrincipalClaimsMappingPolicyResourceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||||||
client := meta.(*clients.Client).ServicePrincipals.ClaimsMappingPolicyClient | ||||||
objectId := d.Id() | ||||||
|
||||||
var definitions []string | ||||||
for _, v := range d.Get("definition").([]interface{}) { | ||||||
definitions = append(definitions, v.(string)) | ||||||
} | ||||||
|
||||||
displayName := d.Get("display_name").(string) | ||||||
|
||||||
claimsMappingPolicy := msgraph.ClaimsMappingPolicy{ | ||||||
DirectoryObject: msgraph.DirectoryObject{ | ||||||
ID: &objectId, | ||||||
}, | ||||||
Definition: &definitions, | ||||||
DisplayName: &displayName, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above |
||||||
} | ||||||
_, err := client.Update(ctx, claimsMappingPolicy) | ||||||
if err != nil { | ||||||
return tf.ErrorDiagF(err, "Could not update ClaimsMappingPolicy %q", displayName) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we can, we prefer to use the object ID in the error text
Suggested change
|
||||||
} | ||||||
|
||||||
return servicePrincipalClaimsMappingPolicyResourceRead(ctx, d, meta) | ||||||
} | ||||||
|
||||||
func servicePrincipalClaimsMappingPolicyResourceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||||||
client := meta.(*clients.Client).ServicePrincipals.ClaimsMappingPolicyClient | ||||||
objectId := d.Id() | ||||||
|
||||||
_, status, err := client.Get(ctx, objectId, odata.Query{}) | ||||||
if err != nil { | ||||||
if status == http.StatusNotFound { | ||||||
return tf.ErrorDiagPathF( | ||||||
fmt.Errorf( | ||||||
"Claims Mapping Policy was not found"), | ||||||
"id", "Retrieving Claims Mapping Policy with object ID %q", | ||||||
objectId, | ||||||
) | ||||||
} | ||||||
|
||||||
return tf.ErrorDiagPathF(err, "id", "Retrieving Claims Mapping Policy with object ID %q", objectId) | ||||||
} | ||||||
|
||||||
status, err = client.Delete(ctx, objectId) | ||||||
if err != nil { | ||||||
return tf.ErrorDiagF(err, "Deleting Claims Mapping Policy with object ID %q, received status %d", objectId, status) | ||||||
} | ||||||
|
||||||
return nil | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
id
can be omitted from the schema as the Terraform Plugin SDK adds this implicitly.