mirror of
https://github.com/hanzokms/terraform-provider.git
synced 2026-10-30 20:29:45 +00:00
857 lines
31 KiB
Go
857 lines
31 KiB
Go
package resource
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
kmsclient "github.com/hanzokms/terraform-provider/internal/client"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
|
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
)
|
|
|
|
var (
|
|
SUPPORTED_SUBJECT_TYPES = []string{"common_name", "organization", "country"}
|
|
SUPPORTED_SAN_TYPES = []string{"dns_name", "ip_address", "email", "uri"}
|
|
SUPPORTED_CERT_KEY_USAGES = []string{
|
|
"digital_signature", "key_encipherment", "non_repudiation",
|
|
"data_encipherment", "key_agreement", "key_cert_sign",
|
|
"crl_sign", "encipher_only", "decipher_only",
|
|
}
|
|
SUPPORTED_CERT_EXT_KEY_USAGES = []string{
|
|
"client_auth", "server_auth", "code_signing",
|
|
"email_protection", "ocsp_signing", "time_stamping",
|
|
}
|
|
SUPPORTED_SIGNATURE_ALGORITHMS = []string{
|
|
"SHA256-RSA", "SHA512-RSA", "SHA384-ECDSA",
|
|
"SHA384-RSA", "SHA256-ECDSA", "SHA512-ECDSA",
|
|
}
|
|
SUPPORTED_KEY_ALGORITHMS = []string{
|
|
"RSA-2048", "RSA-3072", "RSA-4096",
|
|
"ECDSA-P256", "ECDSA-P521", "ECDSA-P384",
|
|
}
|
|
)
|
|
|
|
var (
|
|
_ resource.Resource = &certManagerCertificatePolicyResource{}
|
|
)
|
|
|
|
func NewCertManagerCertificatePolicyResource() resource.Resource {
|
|
return &certManagerCertificatePolicyResource{}
|
|
}
|
|
|
|
type certManagerCertificatePolicyResource struct {
|
|
client *kmsclient.Client
|
|
}
|
|
|
|
type certManagerCertificatePolicySubjectModel struct {
|
|
Type types.String `tfsdk:"type"`
|
|
Allowed types.List `tfsdk:"allowed"`
|
|
Required types.List `tfsdk:"required"`
|
|
Denied types.List `tfsdk:"denied"`
|
|
}
|
|
|
|
type certManagerCertificatePolicySanModel struct {
|
|
Type types.String `tfsdk:"type"`
|
|
Allowed types.List `tfsdk:"allowed"`
|
|
Required types.List `tfsdk:"required"`
|
|
Denied types.List `tfsdk:"denied"`
|
|
}
|
|
|
|
type certManagerCertificatePolicyKeyUsagesModel struct {
|
|
Allowed types.List `tfsdk:"allowed"`
|
|
Required types.List `tfsdk:"required"`
|
|
Denied types.List `tfsdk:"denied"`
|
|
}
|
|
|
|
type certManagerCertificatePolicyExtendedKeyUsagesModel struct {
|
|
Allowed types.List `tfsdk:"allowed"`
|
|
Required types.List `tfsdk:"required"`
|
|
Denied types.List `tfsdk:"denied"`
|
|
}
|
|
|
|
type certManagerCertificatePolicyAlgorithmsModel struct {
|
|
Signature types.List `tfsdk:"signature"`
|
|
KeyAlgorithm types.List `tfsdk:"key_algorithm"`
|
|
}
|
|
|
|
type certManagerCertificatePolicyValidityModel struct {
|
|
Max types.String `tfsdk:"max"`
|
|
}
|
|
|
|
type certManagerCertificatePolicyResourceModel struct {
|
|
ProjectSlug types.String `tfsdk:"project_slug"`
|
|
Id types.String `tfsdk:"id"`
|
|
Name types.String `tfsdk:"name"`
|
|
Description types.String `tfsdk:"description"`
|
|
Subject []certManagerCertificatePolicySubjectModel `tfsdk:"subject"`
|
|
Sans []certManagerCertificatePolicySanModel `tfsdk:"sans"`
|
|
KeyUsages *certManagerCertificatePolicyKeyUsagesModel `tfsdk:"key_usages"`
|
|
ExtendedKeyUsages *certManagerCertificatePolicyExtendedKeyUsagesModel `tfsdk:"extended_key_usages"`
|
|
Algorithms *certManagerCertificatePolicyAlgorithmsModel `tfsdk:"algorithms"`
|
|
Validity *certManagerCertificatePolicyValidityModel `tfsdk:"validity"`
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
|
resp.TypeName = req.ProviderTypeName + "_cert_manager_certificate_policy"
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
|
resp.Schema = schema.Schema{
|
|
Description: "Create and manage certificate policies in Kms. Only Machine Identity authentication is supported for this resource.",
|
|
Attributes: map[string]schema.Attribute{
|
|
"project_slug": schema.StringAttribute{
|
|
Description: "The slug of the cert-manager project",
|
|
Required: true,
|
|
PlanModifiers: []planmodifier.String{
|
|
stringplanmodifier.RequiresReplace(),
|
|
},
|
|
},
|
|
"id": schema.StringAttribute{
|
|
Description: "The ID of the certificate policy",
|
|
Computed: true,
|
|
PlanModifiers: []planmodifier.String{
|
|
stringplanmodifier.UseStateForUnknown(),
|
|
},
|
|
},
|
|
"name": schema.StringAttribute{
|
|
Description: "The name of the certificate policy",
|
|
Required: true,
|
|
},
|
|
"description": schema.StringAttribute{
|
|
Description: "The description of the certificate policy",
|
|
Optional: true,
|
|
},
|
|
},
|
|
Blocks: map[string]schema.Block{
|
|
"subject": schema.ListNestedBlock{
|
|
Description: "Subject attribute policies for the certificate policy",
|
|
NestedObject: schema.NestedBlockObject{
|
|
Attributes: map[string]schema.Attribute{
|
|
"type": schema.StringAttribute{
|
|
Description: "The subject attribute type. Possible values: " + strings.Join(SUPPORTED_SUBJECT_TYPES, ", "),
|
|
Required: true,
|
|
Validators: []validator.String{
|
|
stringvalidator.OneOf(SUPPORTED_SUBJECT_TYPES...),
|
|
},
|
|
},
|
|
"allowed": schema.ListAttribute{
|
|
Description: "List of allowed values for this subject attribute",
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
},
|
|
"required": schema.ListAttribute{
|
|
Description: "List of required values for this subject attribute",
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
},
|
|
"denied": schema.ListAttribute{
|
|
Description: "List of denied values for this subject attribute",
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"sans": schema.ListNestedBlock{
|
|
Description: "Subject alternative name (SAN) policies for the certificate policy",
|
|
NestedObject: schema.NestedBlockObject{
|
|
Attributes: map[string]schema.Attribute{
|
|
"type": schema.StringAttribute{
|
|
Description: "The SAN type. Possible values: " + strings.Join(SUPPORTED_SAN_TYPES, ", "),
|
|
Required: true,
|
|
Validators: []validator.String{
|
|
stringvalidator.OneOf(SUPPORTED_SAN_TYPES...),
|
|
},
|
|
},
|
|
"allowed": schema.ListAttribute{
|
|
Description: "List of allowed values for this SAN type",
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
},
|
|
"required": schema.ListAttribute{
|
|
Description: "List of required values for this SAN type",
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
},
|
|
"denied": schema.ListAttribute{
|
|
Description: "List of denied values for this SAN type",
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"key_usages": schema.SingleNestedBlock{
|
|
Description: "Key usage policies for the certificate policy",
|
|
Attributes: map[string]schema.Attribute{
|
|
"allowed": schema.ListAttribute{
|
|
Description: "List of allowed key usages. Possible values: " + strings.Join(SUPPORTED_CERT_KEY_USAGES, ", "),
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_CERT_KEY_USAGES...)),
|
|
},
|
|
},
|
|
"required": schema.ListAttribute{
|
|
Description: "List of required key usages. Possible values: " + strings.Join(SUPPORTED_CERT_KEY_USAGES, ", "),
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_CERT_KEY_USAGES...)),
|
|
},
|
|
},
|
|
"denied": schema.ListAttribute{
|
|
Description: "List of denied key usages. Possible values: " + strings.Join(SUPPORTED_CERT_KEY_USAGES, ", "),
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_CERT_KEY_USAGES...)),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"extended_key_usages": schema.SingleNestedBlock{
|
|
Description: "Extended key usage policies for the certificate policy",
|
|
Attributes: map[string]schema.Attribute{
|
|
"allowed": schema.ListAttribute{
|
|
Description: "List of allowed extended key usages. Possible values: " + strings.Join(SUPPORTED_CERT_EXT_KEY_USAGES, ", "),
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_CERT_EXT_KEY_USAGES...)),
|
|
},
|
|
},
|
|
"required": schema.ListAttribute{
|
|
Description: "List of required extended key usages. Possible values: " + strings.Join(SUPPORTED_CERT_EXT_KEY_USAGES, ", "),
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_CERT_EXT_KEY_USAGES...)),
|
|
},
|
|
},
|
|
"denied": schema.ListAttribute{
|
|
Description: "List of denied extended key usages. Possible values: " + strings.Join(SUPPORTED_CERT_EXT_KEY_USAGES, ", "),
|
|
Optional: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_CERT_EXT_KEY_USAGES...)),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"algorithms": schema.SingleNestedBlock{
|
|
Description: "Algorithm constraints for the certificate policy. At least one signature algorithm and one key algorithm must be specified.",
|
|
Attributes: map[string]schema.Attribute{
|
|
"signature": schema.ListAttribute{
|
|
Description: "List of allowed signature algorithms (at least one required). Supported values: " + strings.Join(SUPPORTED_SIGNATURE_ALGORITHMS, ", "),
|
|
Required: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_SIGNATURE_ALGORITHMS...)),
|
|
},
|
|
},
|
|
"key_algorithm": schema.ListAttribute{
|
|
Description: "List of allowed key algorithms (at least one required). Supported values: " + strings.Join(SUPPORTED_KEY_ALGORITHMS, ", "),
|
|
Required: true,
|
|
ElementType: types.StringType,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
listvalidator.ValueStringsAre(stringvalidator.OneOf(SUPPORTED_KEY_ALGORITHMS...)),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"validity": schema.SingleNestedBlock{
|
|
Description: "Validity constraints for the certificate policy",
|
|
Attributes: map[string]schema.Attribute{
|
|
"max": schema.StringAttribute{
|
|
Description: "Maximum validity period (e.g., '90d', '2y', '6m')",
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
|
if req.ProviderData == nil {
|
|
return
|
|
}
|
|
|
|
client, ok := req.ProviderData.(*kmsclient.Client)
|
|
if !ok {
|
|
resp.Diagnostics.AddError(
|
|
"Unexpected Resource Configure Type",
|
|
fmt.Sprintf("Expected *kmsclient.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
|
|
)
|
|
return
|
|
}
|
|
|
|
r.client = client
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
|
if !r.client.Config.IsMachineIdentityAuth {
|
|
resp.Diagnostics.AddError(
|
|
"Unable to create certificate policy",
|
|
"Only Machine Identity authentication is supported for this operation",
|
|
)
|
|
return
|
|
}
|
|
|
|
var plan certManagerCertificatePolicyResourceModel
|
|
|
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
project, err := r.client.GetProject(kmsclient.GetProjectRequest{
|
|
Slug: plan.ProjectSlug.ValueString(),
|
|
})
|
|
if err != nil {
|
|
resp.Diagnostics.AddError("Error finding project by slug", err.Error())
|
|
return
|
|
}
|
|
|
|
createPolicyRequest := kmsclient.CreateCertificatePolicyRequest{
|
|
ProjectId: project.ID,
|
|
Name: plan.Name.ValueString(),
|
|
Description: plan.Description.ValueString(),
|
|
}
|
|
|
|
if len(plan.Subject) > 0 {
|
|
createPolicyRequest.Subject = make([]kmsclient.CertificatePolicySubject, len(plan.Subject))
|
|
for i, subj := range plan.Subject {
|
|
createPolicyRequest.Subject[i] = kmsclient.CertificatePolicySubject{
|
|
Type: subj.Type.ValueString(),
|
|
}
|
|
|
|
if !subj.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(subj.Allowed.Elements()))
|
|
resp.Diagnostics.Append(subj.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
createPolicyRequest.Subject[i].Allowed = allowed
|
|
}
|
|
|
|
if !subj.Required.IsNull() {
|
|
required := make([]string, 0, len(subj.Required.Elements()))
|
|
resp.Diagnostics.Append(subj.Required.ElementsAs(ctx, &required, false)...)
|
|
createPolicyRequest.Subject[i].Required = required
|
|
}
|
|
|
|
if !subj.Denied.IsNull() {
|
|
denied := make([]string, 0, len(subj.Denied.Elements()))
|
|
resp.Diagnostics.Append(subj.Denied.ElementsAs(ctx, &denied, false)...)
|
|
createPolicyRequest.Subject[i].Denied = denied
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(plan.Sans) > 0 {
|
|
createPolicyRequest.Sans = make([]kmsclient.CertificatePolicySAN, len(plan.Sans))
|
|
for i, san := range plan.Sans {
|
|
createPolicyRequest.Sans[i] = kmsclient.CertificatePolicySAN{
|
|
Type: san.Type.ValueString(),
|
|
}
|
|
|
|
if !san.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(san.Allowed.Elements()))
|
|
resp.Diagnostics.Append(san.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
createPolicyRequest.Sans[i].Allowed = allowed
|
|
}
|
|
|
|
if !san.Required.IsNull() {
|
|
required := make([]string, 0, len(san.Required.Elements()))
|
|
resp.Diagnostics.Append(san.Required.ElementsAs(ctx, &required, false)...)
|
|
createPolicyRequest.Sans[i].Required = required
|
|
}
|
|
|
|
if !san.Denied.IsNull() {
|
|
denied := make([]string, 0, len(san.Denied.Elements()))
|
|
resp.Diagnostics.Append(san.Denied.ElementsAs(ctx, &denied, false)...)
|
|
createPolicyRequest.Sans[i].Denied = denied
|
|
}
|
|
}
|
|
}
|
|
|
|
if plan.KeyUsages != nil {
|
|
createPolicyRequest.KeyUsages = &kmsclient.CertificatePolicyKeyUsages{}
|
|
|
|
if !plan.KeyUsages.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(plan.KeyUsages.Allowed.Elements()))
|
|
resp.Diagnostics.Append(plan.KeyUsages.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
createPolicyRequest.KeyUsages.Allowed = allowed
|
|
}
|
|
|
|
if !plan.KeyUsages.Required.IsNull() {
|
|
required := make([]string, 0, len(plan.KeyUsages.Required.Elements()))
|
|
resp.Diagnostics.Append(plan.KeyUsages.Required.ElementsAs(ctx, &required, false)...)
|
|
createPolicyRequest.KeyUsages.Required = required
|
|
}
|
|
|
|
if !plan.KeyUsages.Denied.IsNull() {
|
|
denied := make([]string, 0, len(plan.KeyUsages.Denied.Elements()))
|
|
resp.Diagnostics.Append(plan.KeyUsages.Denied.ElementsAs(ctx, &denied, false)...)
|
|
createPolicyRequest.KeyUsages.Denied = denied
|
|
}
|
|
}
|
|
|
|
if plan.ExtendedKeyUsages != nil {
|
|
createPolicyRequest.ExtendedKeyUsages = &kmsclient.CertificatePolicyExtendedKeyUsages{}
|
|
|
|
if !plan.ExtendedKeyUsages.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(plan.ExtendedKeyUsages.Allowed.Elements()))
|
|
resp.Diagnostics.Append(plan.ExtendedKeyUsages.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
createPolicyRequest.ExtendedKeyUsages.Allowed = allowed
|
|
}
|
|
|
|
if !plan.ExtendedKeyUsages.Required.IsNull() {
|
|
required := make([]string, 0, len(plan.ExtendedKeyUsages.Required.Elements()))
|
|
resp.Diagnostics.Append(plan.ExtendedKeyUsages.Required.ElementsAs(ctx, &required, false)...)
|
|
createPolicyRequest.ExtendedKeyUsages.Required = required
|
|
}
|
|
|
|
if !plan.ExtendedKeyUsages.Denied.IsNull() {
|
|
denied := make([]string, 0, len(plan.ExtendedKeyUsages.Denied.Elements()))
|
|
resp.Diagnostics.Append(plan.ExtendedKeyUsages.Denied.ElementsAs(ctx, &denied, false)...)
|
|
createPolicyRequest.ExtendedKeyUsages.Denied = denied
|
|
}
|
|
}
|
|
|
|
if plan.Algorithms != nil {
|
|
createPolicyRequest.Algorithms = &kmsclient.CertificatePolicyAlgorithms{}
|
|
|
|
if !plan.Algorithms.Signature.IsNull() {
|
|
signature := make([]string, 0, len(plan.Algorithms.Signature.Elements()))
|
|
resp.Diagnostics.Append(plan.Algorithms.Signature.ElementsAs(ctx, &signature, false)...)
|
|
createPolicyRequest.Algorithms.Signature = signature
|
|
}
|
|
|
|
if !plan.Algorithms.KeyAlgorithm.IsNull() {
|
|
keyAlgorithm := make([]string, 0, len(plan.Algorithms.KeyAlgorithm.Elements()))
|
|
resp.Diagnostics.Append(plan.Algorithms.KeyAlgorithm.ElementsAs(ctx, &keyAlgorithm, false)...)
|
|
createPolicyRequest.Algorithms.KeyAlgorithm = keyAlgorithm
|
|
}
|
|
}
|
|
|
|
if plan.Validity != nil && !plan.Validity.Max.IsNull() {
|
|
createPolicyRequest.Validity = &kmsclient.CertificatePolicyValidity{
|
|
Max: plan.Validity.Max.ValueString(),
|
|
}
|
|
}
|
|
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
policy, err := r.client.CreateCertificatePolicy(createPolicyRequest)
|
|
if err != nil {
|
|
resp.Diagnostics.AddError("Error creating certificate policy", err.Error())
|
|
return
|
|
}
|
|
|
|
plan.Id = types.StringValue(policy.CertificatePolicy.Id)
|
|
|
|
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
|
if !r.client.Config.IsMachineIdentityAuth {
|
|
resp.Diagnostics.AddError(
|
|
"Unable to read certificate policy",
|
|
"Only Machine Identity authentication is supported for this operation",
|
|
)
|
|
return
|
|
}
|
|
|
|
var currentState certManagerCertificatePolicyResourceModel
|
|
resp.Diagnostics.Append(req.State.Get(ctx, ¤tState)...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
var state certManagerCertificatePolicyResourceModel
|
|
|
|
policy, err := r.client.GetCertificatePolicy(kmsclient.GetCertificatePolicyRequest{
|
|
PolicyId: currentState.Id.ValueString(),
|
|
})
|
|
if err != nil {
|
|
if err == kmsclient.ErrNotFound {
|
|
resp.State.RemoveResource(ctx)
|
|
return
|
|
}
|
|
|
|
resp.Diagnostics.AddError("Error reading certificate policy", err.Error())
|
|
return
|
|
}
|
|
|
|
state.Id = types.StringValue(policy.CertificatePolicy.Id)
|
|
state.ProjectSlug = currentState.ProjectSlug
|
|
state.Name = types.StringValue(policy.CertificatePolicy.Name)
|
|
if policy.CertificatePolicy.Description != "" {
|
|
state.Description = types.StringValue(policy.CertificatePolicy.Description)
|
|
} else {
|
|
state.Description = types.StringNull()
|
|
}
|
|
|
|
if len(policy.CertificatePolicy.Subject) > 0 {
|
|
state.Subject = make([]certManagerCertificatePolicySubjectModel, len(policy.CertificatePolicy.Subject))
|
|
for i, subj := range policy.CertificatePolicy.Subject {
|
|
state.Subject[i] = certManagerCertificatePolicySubjectModel{
|
|
Type: types.StringValue(subj.Type),
|
|
}
|
|
|
|
if len(subj.Allowed) > 0 {
|
|
allowedList, diags := types.ListValueFrom(ctx, types.StringType, subj.Allowed)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Subject[i].Allowed = allowedList
|
|
} else {
|
|
state.Subject[i].Allowed = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(subj.Required) > 0 {
|
|
requiredList, diags := types.ListValueFrom(ctx, types.StringType, subj.Required)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Subject[i].Required = requiredList
|
|
} else {
|
|
if len(currentState.Subject) > i && !currentState.Subject[i].Required.IsNull() {
|
|
state.Subject[i].Required = currentState.Subject[i].Required
|
|
} else {
|
|
state.Subject[i].Required = types.ListNull(types.StringType)
|
|
}
|
|
}
|
|
|
|
if len(subj.Denied) > 0 {
|
|
deniedList, diags := types.ListValueFrom(ctx, types.StringType, subj.Denied)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Subject[i].Denied = deniedList
|
|
} else {
|
|
state.Subject[i].Denied = types.ListNull(types.StringType)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(policy.CertificatePolicy.Sans) > 0 {
|
|
state.Sans = make([]certManagerCertificatePolicySanModel, len(policy.CertificatePolicy.Sans))
|
|
for i, san := range policy.CertificatePolicy.Sans {
|
|
state.Sans[i] = certManagerCertificatePolicySanModel{
|
|
Type: types.StringValue(san.Type),
|
|
}
|
|
|
|
if len(san.Allowed) > 0 {
|
|
allowedList, diags := types.ListValueFrom(ctx, types.StringType, san.Allowed)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Sans[i].Allowed = allowedList
|
|
} else {
|
|
state.Sans[i].Allowed = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(san.Required) > 0 {
|
|
requiredList, diags := types.ListValueFrom(ctx, types.StringType, san.Required)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Sans[i].Required = requiredList
|
|
} else {
|
|
state.Sans[i].Required = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(san.Denied) > 0 {
|
|
deniedList, diags := types.ListValueFrom(ctx, types.StringType, san.Denied)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Sans[i].Denied = deniedList
|
|
} else {
|
|
state.Sans[i].Denied = types.ListNull(types.StringType)
|
|
}
|
|
}
|
|
}
|
|
|
|
if currentState.KeyUsages != nil {
|
|
state.KeyUsages = &certManagerCertificatePolicyKeyUsagesModel{}
|
|
|
|
if policy.CertificatePolicy.KeyUsages != nil {
|
|
if len(policy.CertificatePolicy.KeyUsages.Allowed) > 0 {
|
|
allowedList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.KeyUsages.Allowed)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.KeyUsages.Allowed = allowedList
|
|
} else {
|
|
state.KeyUsages.Allowed = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(policy.CertificatePolicy.KeyUsages.Required) > 0 {
|
|
requiredList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.KeyUsages.Required)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.KeyUsages.Required = requiredList
|
|
} else {
|
|
state.KeyUsages.Required = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(policy.CertificatePolicy.KeyUsages.Denied) > 0 {
|
|
deniedList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.KeyUsages.Denied)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.KeyUsages.Denied = deniedList
|
|
} else {
|
|
state.KeyUsages.Denied = types.ListNull(types.StringType)
|
|
}
|
|
} else {
|
|
state.KeyUsages.Allowed = types.ListNull(types.StringType)
|
|
state.KeyUsages.Required = types.ListNull(types.StringType)
|
|
state.KeyUsages.Denied = types.ListNull(types.StringType)
|
|
}
|
|
}
|
|
|
|
if currentState.ExtendedKeyUsages != nil {
|
|
state.ExtendedKeyUsages = &certManagerCertificatePolicyExtendedKeyUsagesModel{}
|
|
|
|
if policy.CertificatePolicy.ExtendedKeyUsages != nil {
|
|
if len(policy.CertificatePolicy.ExtendedKeyUsages.Allowed) > 0 {
|
|
allowedList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.ExtendedKeyUsages.Allowed)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.ExtendedKeyUsages.Allowed = allowedList
|
|
} else {
|
|
state.ExtendedKeyUsages.Allowed = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(policy.CertificatePolicy.ExtendedKeyUsages.Required) > 0 {
|
|
requiredList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.ExtendedKeyUsages.Required)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.ExtendedKeyUsages.Required = requiredList
|
|
} else {
|
|
state.ExtendedKeyUsages.Required = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(policy.CertificatePolicy.ExtendedKeyUsages.Denied) > 0 {
|
|
deniedList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.ExtendedKeyUsages.Denied)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.ExtendedKeyUsages.Denied = deniedList
|
|
} else {
|
|
state.ExtendedKeyUsages.Denied = types.ListNull(types.StringType)
|
|
}
|
|
} else {
|
|
state.ExtendedKeyUsages.Allowed = types.ListNull(types.StringType)
|
|
state.ExtendedKeyUsages.Required = types.ListNull(types.StringType)
|
|
state.ExtendedKeyUsages.Denied = types.ListNull(types.StringType)
|
|
}
|
|
}
|
|
|
|
if policy.CertificatePolicy.Algorithms != nil {
|
|
state.Algorithms = &certManagerCertificatePolicyAlgorithmsModel{}
|
|
|
|
if len(policy.CertificatePolicy.Algorithms.Signature) > 0 {
|
|
signatureList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.Algorithms.Signature)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Algorithms.Signature = signatureList
|
|
} else {
|
|
state.Algorithms.Signature = types.ListNull(types.StringType)
|
|
}
|
|
|
|
if len(policy.CertificatePolicy.Algorithms.KeyAlgorithm) > 0 {
|
|
keyAlgorithmList, diags := types.ListValueFrom(ctx, types.StringType, policy.CertificatePolicy.Algorithms.KeyAlgorithm)
|
|
resp.Diagnostics.Append(diags...)
|
|
state.Algorithms.KeyAlgorithm = keyAlgorithmList
|
|
} else {
|
|
state.Algorithms.KeyAlgorithm = types.ListNull(types.StringType)
|
|
}
|
|
}
|
|
|
|
if policy.CertificatePolicy.Validity != nil && policy.CertificatePolicy.Validity.Max != "" {
|
|
state.Validity = &certManagerCertificatePolicyValidityModel{
|
|
Max: types.StringValue(policy.CertificatePolicy.Validity.Max),
|
|
}
|
|
}
|
|
|
|
resp.Diagnostics.Append(resp.State.Set(ctx, state)...)
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
|
if !r.client.Config.IsMachineIdentityAuth {
|
|
resp.Diagnostics.AddError(
|
|
"Unable to update certificate policy",
|
|
"Only Machine Identity authentication is supported for this operation",
|
|
)
|
|
return
|
|
}
|
|
|
|
var plan certManagerCertificatePolicyResourceModel
|
|
|
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
updatePolicyRequest := kmsclient.UpdateCertificatePolicyRequest{
|
|
PolicyId: plan.Id.ValueString(),
|
|
Name: plan.Name.ValueString(),
|
|
Description: plan.Description.ValueString(),
|
|
}
|
|
|
|
if len(plan.Subject) > 0 {
|
|
updatePolicyRequest.Subject = make([]kmsclient.CertificatePolicySubject, len(plan.Subject))
|
|
for i, subj := range plan.Subject {
|
|
updatePolicyRequest.Subject[i] = kmsclient.CertificatePolicySubject{
|
|
Type: subj.Type.ValueString(),
|
|
}
|
|
|
|
if !subj.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(subj.Allowed.Elements()))
|
|
resp.Diagnostics.Append(subj.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
updatePolicyRequest.Subject[i].Allowed = allowed
|
|
}
|
|
|
|
if !subj.Required.IsNull() {
|
|
required := make([]string, 0, len(subj.Required.Elements()))
|
|
resp.Diagnostics.Append(subj.Required.ElementsAs(ctx, &required, false)...)
|
|
updatePolicyRequest.Subject[i].Required = required
|
|
}
|
|
|
|
if !subj.Denied.IsNull() {
|
|
denied := make([]string, 0, len(subj.Denied.Elements()))
|
|
resp.Diagnostics.Append(subj.Denied.ElementsAs(ctx, &denied, false)...)
|
|
updatePolicyRequest.Subject[i].Denied = denied
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(plan.Sans) > 0 {
|
|
updatePolicyRequest.Sans = make([]kmsclient.CertificatePolicySAN, len(plan.Sans))
|
|
for i, san := range plan.Sans {
|
|
updatePolicyRequest.Sans[i] = kmsclient.CertificatePolicySAN{
|
|
Type: san.Type.ValueString(),
|
|
}
|
|
|
|
if !san.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(san.Allowed.Elements()))
|
|
resp.Diagnostics.Append(san.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
updatePolicyRequest.Sans[i].Allowed = allowed
|
|
}
|
|
|
|
if !san.Required.IsNull() {
|
|
required := make([]string, 0, len(san.Required.Elements()))
|
|
resp.Diagnostics.Append(san.Required.ElementsAs(ctx, &required, false)...)
|
|
updatePolicyRequest.Sans[i].Required = required
|
|
}
|
|
|
|
if !san.Denied.IsNull() {
|
|
denied := make([]string, 0, len(san.Denied.Elements()))
|
|
resp.Diagnostics.Append(san.Denied.ElementsAs(ctx, &denied, false)...)
|
|
updatePolicyRequest.Sans[i].Denied = denied
|
|
}
|
|
}
|
|
}
|
|
|
|
if plan.KeyUsages != nil {
|
|
updatePolicyRequest.KeyUsages = &kmsclient.CertificatePolicyKeyUsages{}
|
|
|
|
if !plan.KeyUsages.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(plan.KeyUsages.Allowed.Elements()))
|
|
resp.Diagnostics.Append(plan.KeyUsages.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
updatePolicyRequest.KeyUsages.Allowed = allowed
|
|
}
|
|
|
|
if !plan.KeyUsages.Required.IsNull() {
|
|
required := make([]string, 0, len(plan.KeyUsages.Required.Elements()))
|
|
resp.Diagnostics.Append(plan.KeyUsages.Required.ElementsAs(ctx, &required, false)...)
|
|
updatePolicyRequest.KeyUsages.Required = required
|
|
}
|
|
|
|
if !plan.KeyUsages.Denied.IsNull() {
|
|
denied := make([]string, 0, len(plan.KeyUsages.Denied.Elements()))
|
|
resp.Diagnostics.Append(plan.KeyUsages.Denied.ElementsAs(ctx, &denied, false)...)
|
|
updatePolicyRequest.KeyUsages.Denied = denied
|
|
}
|
|
}
|
|
|
|
if plan.ExtendedKeyUsages != nil {
|
|
updatePolicyRequest.ExtendedKeyUsages = &kmsclient.CertificatePolicyExtendedKeyUsages{}
|
|
|
|
if !plan.ExtendedKeyUsages.Allowed.IsNull() {
|
|
allowed := make([]string, 0, len(plan.ExtendedKeyUsages.Allowed.Elements()))
|
|
resp.Diagnostics.Append(plan.ExtendedKeyUsages.Allowed.ElementsAs(ctx, &allowed, false)...)
|
|
updatePolicyRequest.ExtendedKeyUsages.Allowed = allowed
|
|
}
|
|
|
|
if !plan.ExtendedKeyUsages.Required.IsNull() {
|
|
required := make([]string, 0, len(plan.ExtendedKeyUsages.Required.Elements()))
|
|
resp.Diagnostics.Append(plan.ExtendedKeyUsages.Required.ElementsAs(ctx, &required, false)...)
|
|
updatePolicyRequest.ExtendedKeyUsages.Required = required
|
|
}
|
|
|
|
if !plan.ExtendedKeyUsages.Denied.IsNull() {
|
|
denied := make([]string, 0, len(plan.ExtendedKeyUsages.Denied.Elements()))
|
|
resp.Diagnostics.Append(plan.ExtendedKeyUsages.Denied.ElementsAs(ctx, &denied, false)...)
|
|
updatePolicyRequest.ExtendedKeyUsages.Denied = denied
|
|
}
|
|
}
|
|
|
|
if plan.Algorithms != nil {
|
|
updatePolicyRequest.Algorithms = &kmsclient.CertificatePolicyAlgorithms{}
|
|
|
|
if !plan.Algorithms.Signature.IsNull() {
|
|
signature := make([]string, 0, len(plan.Algorithms.Signature.Elements()))
|
|
resp.Diagnostics.Append(plan.Algorithms.Signature.ElementsAs(ctx, &signature, false)...)
|
|
updatePolicyRequest.Algorithms.Signature = signature
|
|
}
|
|
|
|
if !plan.Algorithms.KeyAlgorithm.IsNull() {
|
|
keyAlgorithm := make([]string, 0, len(plan.Algorithms.KeyAlgorithm.Elements()))
|
|
resp.Diagnostics.Append(plan.Algorithms.KeyAlgorithm.ElementsAs(ctx, &keyAlgorithm, false)...)
|
|
updatePolicyRequest.Algorithms.KeyAlgorithm = keyAlgorithm
|
|
}
|
|
}
|
|
|
|
if plan.Validity != nil && !plan.Validity.Max.IsNull() {
|
|
updatePolicyRequest.Validity = &kmsclient.CertificatePolicyValidity{
|
|
Max: plan.Validity.Max.ValueString(),
|
|
}
|
|
}
|
|
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
_, err := r.client.UpdateCertificatePolicy(updatePolicyRequest)
|
|
if err != nil {
|
|
resp.Diagnostics.AddError("Error updating certificate policy", err.Error())
|
|
return
|
|
}
|
|
|
|
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
|
if !r.client.Config.IsMachineIdentityAuth {
|
|
resp.Diagnostics.AddError(
|
|
"Unable to delete certificate policy",
|
|
"Only Machine Identity authentication is supported for this operation",
|
|
)
|
|
return
|
|
}
|
|
|
|
var state certManagerCertificatePolicyResourceModel
|
|
|
|
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
_, err := r.client.DeleteCertificatePolicy(kmsclient.DeleteCertificatePolicyRequest{
|
|
PolicyId: state.Id.ValueString(),
|
|
})
|
|
if err != nil {
|
|
resp.Diagnostics.AddError("Error deleting certificate policy", err.Error())
|
|
return
|
|
}
|
|
}
|
|
|
|
func (r *certManagerCertificatePolicyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
|
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
|
}
|