From c20a060e6a99efaa0ef0a890c52b5bbd9a3427a9 Mon Sep 17 00:00:00 2001 From: Icerzack Date: Mon, 29 Jul 2024 15:39:39 +0300 Subject: [PATCH 1/8] updates --- go.mod | 2 +- go.sum | 4 +- selectel/provider.go | 8 + ...ctel_iam_saml_federation_certificate_v1.go | 163 ++++++++++++++++++ ...iam_saml_federation_certificate_v1_test.go | 1 + ...esource_selectel_iam_saml_federation_v1.go | 162 +++++++++++++++++ ...ce_selectel_iam_saml_federation_v1_test.go | 1 + 7 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 selectel/resource_selectel_iam_saml_federation_certificate_v1.go create mode 100644 selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go create mode 100644 selectel/resource_selectel_iam_saml_federation_v1.go create mode 100644 selectel/resource_selectel_iam_saml_federation_v1_test.go diff --git a/go.mod b/go.mod index 6370eb94..83700a76 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/selectel/dbaas-go v0.12.1 github.com/selectel/domains-go v1.0.2 github.com/selectel/go-selvpcclient/v3 v3.1.1 - github.com/selectel/iam-go v0.2.0 + github.com/selectel/iam-go v0.4.0 github.com/selectel/mks-go v0.14.0 github.com/selectel/secretsmanager-go v0.2.1 github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index 3949d19d..19d26790 100644 --- a/go.sum +++ b/go.sum @@ -170,8 +170,8 @@ github.com/selectel/domains-go v1.0.2 h1:Si6iGaMnTFJxwiJVI50DOdZnwcxc87kqaWrVQYW github.com/selectel/domains-go v1.0.2/go.mod h1:SugRKfq4sTpnOHquslCpzda72wV8u0cMBHx0C0l+bzA= github.com/selectel/go-selvpcclient/v3 v3.1.1 h1:C1q2LqqosiapoLpnGITGmysg0YCSQYDo2Gh69CioevM= github.com/selectel/go-selvpcclient/v3 v3.1.1/go.mod h1:NM7IXhh1IzqZ88DOw1Qc5Ez3tULLViXo95l5+rKPuyQ= -github.com/selectel/iam-go v0.2.0 h1:c6ldpbsa/8R3b29ML5B21FU9oyJ2A2AwBNzCbE+pGN8= -github.com/selectel/iam-go v0.2.0/go.mod h1:OIAkW7MZK97YUm+uvUgYbgDhkI9SdzTCxwd4yZoOR1o= +github.com/selectel/iam-go v0.4.0 h1:jlFUqSNt0NXO9BAP4MUpDg7pi+bncfWJ2eGDOkXMbo8= +github.com/selectel/iam-go v0.4.0/go.mod h1:OIAkW7MZK97YUm+uvUgYbgDhkI9SdzTCxwd4yZoOR1o= github.com/selectel/mks-go v0.14.0 h1:huNq/oTutPc3ezB8HRqlGN9WJubTDETpNKuIVqcZOn0= github.com/selectel/mks-go v0.14.0/go.mod h1:VxtV3dzwgOEzZc+9VMQb9DvxfSlej2ZQ8jnT8kqIGgU= github.com/selectel/secretsmanager-go v0.2.1 h1:OSBrA/07lm/Ecpwg59IJHFAoUHZR29oyfwUgTpr/dos= diff --git a/selectel/provider.go b/selectel/provider.go index a8d2c8ba..a87d1960 100644 --- a/selectel/provider.go +++ b/selectel/provider.go @@ -27,6 +27,10 @@ const ( objectUser = "user" objectServiceUser = "service user" objectS3Credentials = "s3 credentials" + objectGroup = "group" + objectGroupMembership = "group-membership" + objectSAMLFederation = "saml federation" + objectSAMLFederationCertificate = "saml federation certificate" objectCluster = "cluster" objectKubeConfig = "kubeconfig" objectKubeVersions = "kube-versions" @@ -135,6 +139,10 @@ func Provider() *schema.Provider { "selectel_iam_serviceuser_v1": resourceIAMServiceUserV1(), "selectel_iam_user_v1": resourceIAMUserV1(), "selectel_iam_s3_credentials_v1": resourceIAMS3CredentialsV1(), + "selectel_iam_group_v1": resourceIAMGroupV1(), + "selectel_iam_group_membership_v1": resourceIAMGroupMembershipV1(), + "selectel_iam_saml_federation_v1": resourceIAMSAMLFederationV1(), + "selectel_iam_saml_federation_certificate_v1": resourceIAMSAMLFederationCertificateV1(), "selectel_vpc_vrrp_subnet_v2": resourceVPCVRRPSubnetV2(), // DEPRECATED "selectel_vpc_crossregion_subnet_v2": resourceVPCCrossRegionSubnetV2(), // DEPRECATED "selectel_mks_cluster_v1": resourceMKSClusterV1(), diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go new file mode 100644 index 00000000..ca75b4bd --- /dev/null +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go @@ -0,0 +1,163 @@ +package selectel + +import ( + "context" + "errors" + "fmt" + "github.com/selectel/iam-go/service/federations/saml/certificates" + "log" + "os" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/selectel/iam-go/iamerrors" +) + +func resourceIAMSAMLFederationCertificateV1() *schema.Resource { + return &schema.Resource{ + Description: "Represents a SAML Federation Certificate in IAM API", + CreateContext: resourceIAMSAMLFederationCertificateV1Create, + ReadContext: resourceIAMSAMLFederationCertificateV1Read, + UpdateContext: resourceIAMSAMLFederationCertificateV1Update, + DeleteContext: resourceIAMSAMLFederationCertificateV1Delete, + Importer: &schema.ResourceImporter{ + StateContext: resourceIAMS3SAMLFederationCertificateV1ImportState, + }, + Schema: map[string]*schema.Schema{ + "federation_id": { + Type: schema.TypeString, + Required: true, + Description: "Federation ID to create Certificate for.", + }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the Certificate.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Description of the Certificate.", + }, + "data": { + Type: schema.TypeString, + Required: true, + Description: "Certificate issued on the provider side. It must begin with -----BEGIN CERTIFICATE----- and end with -----END CERTIFICATE-----.", + }, + "account_id": { + Type: schema.TypeString, + Computed: true, + Description: "Account ID.", + }, + "not_before": { + Type: schema.TypeString, + Computed: true, + Description: "Certificate lifetime left bound.", + }, + "not_after": { + Type: schema.TypeString, + Computed: true, + Description: "Certificate lifetime right bound.", + }, + "fingerprint": { + Type: schema.TypeString, + Computed: true, + Description: "Fingerprint.", + }, + }, + } +} + +func resourceIAMSAMLFederationCertificateV1Create(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + log.Print(msgCreate(objectSAMLFederationCertificate, d.Id())) + federation, err := iamClient.SAMLFederations.Certificates.Create(ctx, d.Get("federation_id").(string), certificates.CreateRequest{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Data: d.Get("data").(string), + }) + if err != nil { + return diag.FromErr(errCreatingObject(objectSAMLFederationCertificate, err)) + } + + d.SetId(federation.ID) + + return resourceIAMServiceUserV1Read(ctx, d, meta) +} + +func resourceIAMSAMLFederationCertificateV1Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + log.Print(msgGet(objectSAMLFederationCertificate, d.Id())) + certificate, err := iamClient.SAMLFederations.Certificates.Get(ctx, d.Get("federation_id").(string), d.Id()) + if err != nil { + return diag.FromErr(errGettingObject(objectSAMLFederationCertificate, d.Id(), err)) + } + + d.Set("account_id", certificate.AccountID) + d.Set("federation_id", certificate.FederationID) + d.Set("name", certificate.Name) + d.Set("description", certificate.Description) + d.Set("not_before", certificate.NotBefore) + d.Set("not_after", certificate.NotAfter) + d.Set("fingerprint", certificate.Fingerprint) + d.Set("data", certificate.Data) + + return nil +} + +func resourceIAMSAMLFederationCertificateV1Update(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + desc := d.Get("description").(string) + + opts := certificates.UpdateRequest{ + Name: d.Get("name").(string), + Description: &desc, + } + + log.Print(msgUpdate(objectSAMLFederationCertificate, d.Id(), opts)) + _, err := iamClient.SAMLFederations.Certificates.Update(ctx, d.Get("federation_id").(string), d.Id(), opts) + if err != nil { + return diag.FromErr(errUpdatingObject(objectSAMLFederationCertificate, d.Id(), err)) + } + + return resourceIAMServiceUserV1Read(ctx, d, meta) +} + +func resourceIAMSAMLFederationCertificateV1Delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + log.Print(msgDelete(objectSAMLFederationCertificate, d.Id())) + err := iamClient.SAMLFederations.Certificates.Delete(ctx, d.Get("federation_id").(string), d.Id()) + if err != nil && !errors.Is(err, iamerrors.ErrFederationNotFound) { + return diag.FromErr(errDeletingObject(objectSAMLFederationCertificate, d.Id(), err)) + } + + return nil +} + +func resourceIAMS3SAMLFederationCertificateV1ImportState(_ context.Context, d *schema.ResourceData, _ interface{}) ([]*schema.ResourceData, error) { + var v string + if v = os.Getenv("OS_SAML_FEDERATION_ID"); v == "" { + return nil, fmt.Errorf("no OS_SAML_FEDERATION_ID environment variable was found, provide one to use import") + } + + d.Set("federation_id", v) + + return []*schema.ResourceData{d}, nil +} diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go new file mode 100644 index 00000000..7bbb2faa --- /dev/null +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go @@ -0,0 +1 @@ +package selectel diff --git a/selectel/resource_selectel_iam_saml_federation_v1.go b/selectel/resource_selectel_iam_saml_federation_v1.go new file mode 100644 index 00000000..70dbdb1a --- /dev/null +++ b/selectel/resource_selectel_iam_saml_federation_v1.go @@ -0,0 +1,162 @@ +package selectel + +import ( + "context" + "errors" + "github.com/selectel/iam-go/service/federations/saml" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/selectel/iam-go/iamerrors" +) + +func resourceIAMSAMLFederationV1() *schema.Resource { + return &schema.Resource{ + Description: "Represents a SAML Federation in IAM API", + CreateContext: resourceIAMSAMLFederationV1Create, + ReadContext: resourceIAMSAMLFederationV1Read, + UpdateContext: resourceIAMSAMLFederationV1Update, + DeleteContext: resourceIAMSAMLFederationV1Delete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the Federation", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Description of the Federation.", + }, + "issuer": { + Type: schema.TypeString, + Required: true, + Description: "IdP server endpoint URL.", + }, + "sso_url": { + Type: schema.TypeString, + Required: true, + Description: "Single sign-on endpoint URL.", + }, + "sign_authn_requests": { + Type: schema.TypeBool, + Required: true, + Description: "Should sign authentication requests.", + }, + "session_max_age_hours": { + Type: schema.TypeInt, + Required: true, + Description: "Session lifetime.", + }, + "force_authn": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Enable forced authentication at every login.", + }, + "account_id": { + Type: schema.TypeString, + Computed: true, + Description: "Account ID", + }, + }, + } +} + +func resourceIAMSAMLFederationV1Create(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + log.Print(msgCreate(objectSAMLFederation, d.Id())) + federation, err := iamClient.SAMLFederations.Create(ctx, saml.CreateRequest{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Issuer: d.Get("issuer").(string), + SSOUrl: d.Get("sso_url").(string), + SignAuthnRequests: d.Get("sign_authn_requests").(bool), + ForceAuthn: d.Get("force_authn").(bool), + SessionMaxAgeHours: d.Get("session_max_age_hours").(int), + }) + if err != nil { + return diag.FromErr(errCreatingObject(objectSAMLFederation, err)) + } + + d.SetId(federation.ID) + + return resourceIAMServiceUserV1Read(ctx, d, meta) +} + +func resourceIAMSAMLFederationV1Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + log.Print(msgGet(objectSAMLFederation, d.Id())) + federation, err := iamClient.SAMLFederations.Get(ctx, d.Id()) + if err != nil { + return diag.FromErr(errGettingObject(objectSAMLFederation, d.Id(), err)) + } + + d.Set("account_id", federation.AccountID) + d.Set("name", federation.Name) + d.Set("description", federation.Description) + d.Set("issuer", federation.Issuer) + d.Set("sso_url", federation.SSOUrl) + d.Set("sign_authn_requests", federation.SignAuthnRequests) + d.Set("force_authn", federation.ForceAuthn) + d.Set("session_max_age_hours", federation.SessionMaxAgeHours) + + return nil +} + +func resourceIAMSAMLFederationV1Update(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + signAuthnRequests := d.Get("sign_authn_requests").(bool) + forceAuthn := d.Get("force_authn").(bool) + description := d.Get("description").(string) + + opts := saml.UpdateRequest{ + Name: d.Get("name").(string), + Description: &description, + Issuer: d.Get("issuer").(string), + SSOUrl: d.Get("sso_url").(string), + SignAuthnRequests: &signAuthnRequests, + ForceAuthn: &forceAuthn, + SessionMaxAgeHours: d.Get("session_max_age_hours").(int), + } + + log.Print(msgUpdate(objectSAMLFederation, d.Id(), opts)) + err := iamClient.SAMLFederations.Update(ctx, d.Id(), opts) + if err != nil { + return diag.FromErr(errUpdatingObject(objectSAMLFederation, d.Id(), err)) + } + + return resourceIAMServiceUserV1Read(ctx, d, meta) +} + +func resourceIAMSAMLFederationV1Delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + iamClient, diagErr := getIAMClient(meta) + if diagErr != nil { + return diagErr + } + + log.Print(msgDelete(objectSAMLFederation, d.Id())) + err := iamClient.SAMLFederations.Delete(ctx, d.Id()) + if err != nil && !errors.Is(err, iamerrors.ErrFederationNotFound) { + return diag.FromErr(errDeletingObject(objectSAMLFederation, d.Id(), err)) + } + + return nil +} diff --git a/selectel/resource_selectel_iam_saml_federation_v1_test.go b/selectel/resource_selectel_iam_saml_federation_v1_test.go new file mode 100644 index 00000000..7bbb2faa --- /dev/null +++ b/selectel/resource_selectel_iam_saml_federation_v1_test.go @@ -0,0 +1 @@ +package selectel From c257d464fea7132c6c90a787410e06bdf08550f7 Mon Sep 17 00:00:00 2001 From: Icerzack Date: Mon, 29 Jul 2024 16:36:00 +0300 Subject: [PATCH 2/8] tests --- ...ctel_iam_saml_federation_certificate_v1.go | 5 +- ...iam_saml_federation_certificate_v1_test.go | 108 ++++++++++++++++++ ...esource_selectel_iam_saml_federation_v1.go | 4 +- ...ce_selectel_iam_saml_federation_v1_test.go | 91 +++++++++++++++ 4 files changed, 203 insertions(+), 5 deletions(-) diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go index ca75b4bd..6989e5ee 100644 --- a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go @@ -87,7 +87,7 @@ func resourceIAMSAMLFederationCertificateV1Create(ctx context.Context, d *schema d.SetId(federation.ID) - return resourceIAMServiceUserV1Read(ctx, d, meta) + return resourceIAMSAMLFederationCertificateV1Read(ctx, d, meta) } func resourceIAMSAMLFederationCertificateV1Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -103,7 +103,6 @@ func resourceIAMSAMLFederationCertificateV1Read(ctx context.Context, d *schema.R } d.Set("account_id", certificate.AccountID) - d.Set("federation_id", certificate.FederationID) d.Set("name", certificate.Name) d.Set("description", certificate.Description) d.Set("not_before", certificate.NotBefore) @@ -133,7 +132,7 @@ func resourceIAMSAMLFederationCertificateV1Update(ctx context.Context, d *schema return diag.FromErr(errUpdatingObject(objectSAMLFederationCertificate, d.Id(), err)) } - return resourceIAMServiceUserV1Read(ctx, d, meta) + return resourceIAMSAMLFederationCertificateV1Read(ctx, d, meta) } func resourceIAMSAMLFederationCertificateV1Delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go index 7bbb2faa..879db834 100644 --- a/selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1_test.go @@ -1 +1,109 @@ package selectel + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +var cert = `-----BEGIN CERTIFICATE-----\nMIICmzCCAYMCBgGI6ANFczANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjMwNjIzMTEyNjQ4WhcNMzMwNjIzMTEyODI4WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC04rOaDpre/MucE3HXVCnAnpqIqQOeMn696AW2FATnI26x1BsxVAGjcrheAOIu+CxC28m48Ah4+SiTEk/u2X/WbGTd/1GZooz37cge0AWMQGyh8ysZRd6q06kg4QGD1iUtdQyHioMbSr9pPne2QQgSX5/gM9XDuA6dpG9Yv0PIPLFlk3BIUL1qEfUiYbDlrunkN/y4XromJaJPpgXKWraH194bqcgXGQLrCqicKwsRBoQJHg3ODWHjHFOwYODJ1XBsRcAue4J88PKiPV1tZNPVczMptrkqGBYTgOYGjKXGe5EH50RJE4/3Ynurz2s34DSDVJhJOYtGwpfeSuU3i3mVAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGAweCuWJmJXMUdRtgoFIiu6BGotDX5sA/VOm4CRsEXV7/qnBagrAPkRz86KGm4lOPL0X+I13JQh4/OB1gxnPN+BXhNtCWCoj1wA3/BWjs1ow/gaVXzwdy+1mbc/sUBudsLq2Yqs54GgeYsTBKMVpSLKiRg1NebEFlqFmG2hjPzYg1QHL4VBusMQgqt7TTnOfGtdT3Ss9TKGRQ+iwfNL0BtSAKaTRdhNVU4lDYUs788Kw5od/uJj0wTICKO5/PrkX7Uy42+fyU+4SvJynPOy+M+z+s08JC9+eYXixfeeFG1nNWR+DIKXcXaSwNQW+8RweGbOJxQ2BoUKtl0NCHrvxJw=\n-----END CERTIFICATE-----` + +func TestAccIAMV1SAMLFederationCertificateBasic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccSelectelPreCheck(t) }, + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIAMV1SAMLFederationCertificateBasic(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "id"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "name", "cert"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "description", "simple description"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "data"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "not_before"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "not_after"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "fingerprint"), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccIAMV1SAMLFederationCertificateUpdate(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccSelectelPreCheck(t) }, + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIAMV1SAMLFederationCertificateBasic(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "id"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "name", "cert"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "description", "simple description"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "data"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "not_before"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "not_after"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "fingerprint"), + ), + ExpectNonEmptyPlan: true, + }, + { + Config: testAccIAMV1SAMLFederationCertificateUpdate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "id"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "name", "cert 2"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "description", "simple description 2"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "data"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "not_before"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "not_after"), + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_certificate_v1.certificate_tf_acc_test_1", "fingerprint"), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccIAMV1SAMLFederationCertificateBasic() string { + return fmt.Sprintf(` +resource "selectel_iam_saml_federation_v1" "federation_tf_acc_test_1" { + name = "federation name" + description = "simple description" + issuer = "http://localhost:8080/realms/master" + sso_url = "http://localhost:8080/realms/master/protocol/saml" + sign_authn_requests = true + force_authn = true + session_max_age_hours = 24 +} + +resource "selectel_iam_saml_federation_certificate_v1" "certificate_tf_acc_test_1" { + federation_id = selectel_iam_saml_federation_v1.federation_tf_acc_test_1.id + name = "cert" + description = "simple description" + data = "%s" +} +`, cert) +} + +func testAccIAMV1SAMLFederationCertificateUpdate() string { + return fmt.Sprintf(` +resource "selectel_iam_saml_federation_v1" "federation_tf_acc_test_1" { + name = "federation name" + description = "simple description" + issuer = "http://localhost:8080/realms/master" + sso_url = "http://localhost:8080/realms/master/protocol/saml" + sign_authn_requests = true + force_authn = true + session_max_age_hours = 24 +} + +resource "selectel_iam_saml_federation_certificate_v1" "certificate_tf_acc_test_1" { + federation_id = selectel_iam_saml_federation_v1.federation_tf_acc_test_1.id + name = "cert 2" + description = "simple description 2" + data = "%s" +} +`, cert) +} diff --git a/selectel/resource_selectel_iam_saml_federation_v1.go b/selectel/resource_selectel_iam_saml_federation_v1.go index 70dbdb1a..eaf94c9b 100644 --- a/selectel/resource_selectel_iam_saml_federation_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_v1.go @@ -90,7 +90,7 @@ func resourceIAMSAMLFederationV1Create(ctx context.Context, d *schema.ResourceDa d.SetId(federation.ID) - return resourceIAMServiceUserV1Read(ctx, d, meta) + return resourceIAMSAMLFederationV1Read(ctx, d, meta) } func resourceIAMSAMLFederationV1Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -143,7 +143,7 @@ func resourceIAMSAMLFederationV1Update(ctx context.Context, d *schema.ResourceDa return diag.FromErr(errUpdatingObject(objectSAMLFederation, d.Id(), err)) } - return resourceIAMServiceUserV1Read(ctx, d, meta) + return resourceIAMSAMLFederationV1Read(ctx, d, meta) } func resourceIAMSAMLFederationV1Delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { diff --git a/selectel/resource_selectel_iam_saml_federation_v1_test.go b/selectel/resource_selectel_iam_saml_federation_v1_test.go index 7bbb2faa..1e71b5e3 100644 --- a/selectel/resource_selectel_iam_saml_federation_v1_test.go +++ b/selectel/resource_selectel_iam_saml_federation_v1_test.go @@ -1 +1,92 @@ package selectel + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccIAMV1SAMLFederationBasic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccSelectelPreCheck(t) }, + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIAMV1SAMLFederationBasic(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "id"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "name", "federation name"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "description", "simple description"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "issuer", "http://localhost:8080/realms/master"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "sso_url", "http://localhost:8080/realms/master/protocol/saml"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "sign_authn_requests", "true"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "force_authn", "true"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "session_max_age_hours", "24"), + ), + }, + }, + }) +} + +func TestAccIAMV1SAMLFederationUpdate(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccSelectelPreCheck(t) }, + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIAMV1SAMLFederationBasic(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "id"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "name", "federation name"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "description", "simple description"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "issuer", "http://localhost:8080/realms/master"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "sso_url", "http://localhost:8080/realms/master/protocol/saml"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "sign_authn_requests", "true"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "force_authn", "true"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "session_max_age_hours", "24"), + ), + }, + { + Config: testAccIAMV1SAMLFederationUpdate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "id"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "name", "federation name 2"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "description", "simple description 2"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "issuer", "http://localhost:8080/realms/master"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "sso_url", "http://localhost:8080/realms/master/protocol/saml"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "sign_authn_requests", "true"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "force_authn", "true"), + resource.TestCheckResourceAttr("selectel_iam_saml_federation_v1.federation_tf_acc_test_1", "session_max_age_hours", "24"), + ), + }, + }, + }) +} + +func testAccIAMV1SAMLFederationBasic() string { + return ` +resource "selectel_iam_saml_federation_v1" "federation_tf_acc_test_1" { + name = "federation name" + description = "simple description" + issuer = "http://localhost:8080/realms/master" + sso_url = "http://localhost:8080/realms/master/protocol/saml" + sign_authn_requests = true + force_authn = true + session_max_age_hours = 24 +} +` +} + +func testAccIAMV1SAMLFederationUpdate() string { + return ` +resource "selectel_iam_saml_federation_v1" "federation_tf_acc_test_1" { + name = "federation name 2" + description = "simple description 2" + issuer = "http://localhost:8080/realms/master" + sso_url = "http://localhost:8080/realms/master/protocol/saml" + sign_authn_requests = true + force_authn = true + session_max_age_hours = 24 +} +` +} From faaa7cafbb7a06c30e74121bd0cbbe7e9cb9cb0e Mon Sep 17 00:00:00 2001 From: Icerzack Date: Mon, 29 Jul 2024 16:59:39 +0300 Subject: [PATCH 3/8] docs --- selectel/provider.go | 78 +++++++++---------- ...ctel_iam_saml_federation_certificate_v1.go | 2 +- ...esource_selectel_iam_saml_federation_v1.go | 2 +- ...ml_federation_certificate_v1.html.markdown | 69 ++++++++++++++++ .../r/iam_saml_federation_v1.html.markdown | 68 ++++++++++++++++ 5 files changed, 178 insertions(+), 41 deletions(-) create mode 100644 website/docs/r/iam_saml_federation_certificate_v1.html.markdown create mode 100644 website/docs/r/iam_saml_federation_v1.html.markdown diff --git a/selectel/provider.go b/selectel/provider.go index a87d1960..d0114b0a 100644 --- a/selectel/provider.go +++ b/selectel/provider.go @@ -14,47 +14,47 @@ const ( ) const ( - objectACL = "acl" - objectFloatingIP = "floating IP" - objectKeypair = "keypair" - objectLicense = "license" - objectProject = "project" - objectProjectQuotas = "quotas for project" - objectRole = "role" - objectSubnet = "subnet" - objectToken = "token" - objectTopic = "topic" - objectUser = "user" - objectServiceUser = "service user" - objectS3Credentials = "s3 credentials" - objectGroup = "group" - objectGroupMembership = "group-membership" + objectACL = "acl" + objectFloatingIP = "floating IP" + objectKeypair = "keypair" + objectLicense = "license" + objectProject = "project" + objectProjectQuotas = "quotas for project" + objectRole = "role" + objectSubnet = "subnet" + objectToken = "token" + objectTopic = "topic" + objectUser = "user" + objectServiceUser = "service user" + objectS3Credentials = "s3 credentials" + objectGroup = "group" + objectGroupMembership = "group-membership" objectSAMLFederation = "saml federation" objectSAMLFederationCertificate = "saml federation certificate" - objectCluster = "cluster" - objectKubeConfig = "kubeconfig" - objectKubeVersions = "kube-versions" - objectNodegroup = "nodegroup" - objectDomain = "domain" - objectRecord = "record" - objectZone = "zone" - objectRRSet = "rrset" - objectDatastore = "datastore" - objectDatabase = "database" - objectGrant = "grant" - objectExtension = "extension" - objectDatastoreTypes = "datastore-types" - objectAvailableExtensions = "available-extensions" - objectFlavors = "flavors" - objectConfigurationParameters = "configuration-parameters" - objectPrometheusMetricToken = "prometheus-metric-token" - objectFeatureGates = "feature-gates" - objectAdmissionControllers = "admission-controllers" - objectLogicalReplicationSlot = "logical-replication-slot" - objectRegistry = "registry" - objectRegistryToken = "registry token" - objectSecret = "secret" - objectCertificate = "certificate" + objectCluster = "cluster" + objectKubeConfig = "kubeconfig" + objectKubeVersions = "kube-versions" + objectNodegroup = "nodegroup" + objectDomain = "domain" + objectRecord = "record" + objectZone = "zone" + objectRRSet = "rrset" + objectDatastore = "datastore" + objectDatabase = "database" + objectGrant = "grant" + objectExtension = "extension" + objectDatastoreTypes = "datastore-types" + objectAvailableExtensions = "available-extensions" + objectFlavors = "flavors" + objectConfigurationParameters = "configuration-parameters" + objectPrometheusMetricToken = "prometheus-metric-token" + objectFeatureGates = "feature-gates" + objectAdmissionControllers = "admission-controllers" + objectLogicalReplicationSlot = "logical-replication-slot" + objectRegistry = "registry" + objectRegistryToken = "registry token" + objectSecret = "secret" + objectCertificate = "certificate" ) // This is a global MutexKV for use within this plugin. diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go index 6989e5ee..81787374 100644 --- a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go @@ -4,13 +4,13 @@ import ( "context" "errors" "fmt" - "github.com/selectel/iam-go/service/federations/saml/certificates" "log" "os" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/selectel/iam-go/iamerrors" + "github.com/selectel/iam-go/service/federations/saml/certificates" ) func resourceIAMSAMLFederationCertificateV1() *schema.Resource { diff --git a/selectel/resource_selectel_iam_saml_federation_v1.go b/selectel/resource_selectel_iam_saml_federation_v1.go index eaf94c9b..de982b9e 100644 --- a/selectel/resource_selectel_iam_saml_federation_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_v1.go @@ -3,12 +3,12 @@ package selectel import ( "context" "errors" - "github.com/selectel/iam-go/service/federations/saml" "log" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/selectel/iam-go/iamerrors" + "github.com/selectel/iam-go/service/federations/saml" ) func resourceIAMSAMLFederationV1() *schema.Resource { diff --git a/website/docs/r/iam_saml_federation_certificate_v1.html.markdown b/website/docs/r/iam_saml_federation_certificate_v1.html.markdown new file mode 100644 index 00000000..d0333d0b --- /dev/null +++ b/website/docs/r/iam_saml_federation_certificate_v1.html.markdown @@ -0,0 +1,69 @@ +--- +layout: "selectel" +page_title: "Selectel: selectel_iam_saml_federation_certificate_v1" +sidebar_current: "docs-selectel-resource-iam-saml-federation-certificate-v1" +description: |- + Creates and manages SAML Federation Certificates for Selectel products using public API v1. +--- + +# selectel\_iam\_saml\_federation\_certificate\_v1 + +Manages SAML Federation Certificates for Selectel products using public API v1. +Selectel products support Identity and Access Management (IAM). +For more information about Federation Certificates, see the [official Selectel documentation](https://docs.selectel.ru/en/control-panel-actions/users-and-roles/federations/certificates/). + +## Example Usage + +```hcl +resource "selectel_iam_saml_federation_certificate_v1" "certificate" { + federation_id = selectel_iam_saml_federation_v1.federation_1.id + name = "certificate name" + description = "simple description" + data = file("${path.module}/federation_cert.crt") +} + +``` + +## Argument Reference + +* `federation_id` - (Required) Federation ID. + +* `name` - (Required) Certificate name. + +* `description` - (Optional) Certificate description. + +* `data` - (Required) Certificate data. It must begin with -----BEGIN CERTIFICATE----- and end with -----END CERTIFICATE-----. + +## Attributes Reference + +* `account_id` - Federation account ID. + +* `not_before` - Issuing date. + +* `not_after` - End date. + +* `fingerprint` - Fingerprint. + +## Import + +You can import a certificate: + +```shell +export OS_DOMAIN_NAME= +export OS_USERNAME= +export OS_PASSWORD= +export OS_SAML_FEDERATION_ID= +terraform import selectel_iam_saml_federation_certificate_v1.certificate_1 +``` + +where: + +* `` — Selectel account ID. The account ID is in the top right corner of the [Control panel](https://my.selectel.ru/). Learn more about [Registration](https://docs.selectel.ru/en/control-panel-actions/account/registration/). + +* `` — Name of the service user. To get the name, in the [Control panel](https://my.selectel.ru/iam/users_management/users?type=service), go to **Identity & Access Management** ⟶ **User management** ⟶ the **Service users** tab ⟶ copy the name of the required user. Learn more about [Service Users](https://docs.selectel.ru/en/control-panel-actions/users-and-roles/user-types-and-roles/). + +* `` — Password of the service user. + +* `` — Unique identifier of the Federation, which has this certificate, for example, `abc1bb378ac84e1234b869b77aadd2ab`. To get the federation ID, use either [Control Panel](https://my.selectel.ru/iam/federations) or [IAM API](https://developers.selectel.ru/docs/control-panel/iam/) + +* `` — Unique identifier of the Certificate. diff --git a/website/docs/r/iam_saml_federation_v1.html.markdown b/website/docs/r/iam_saml_federation_v1.html.markdown new file mode 100644 index 00000000..36b14d98 --- /dev/null +++ b/website/docs/r/iam_saml_federation_v1.html.markdown @@ -0,0 +1,68 @@ +--- +layout: "selectel" +page_title: "Selectel: selectel_iam_saml_federation_v1" +sidebar_current: "docs-selectel-resource-iam-saml-federation-v1" +description: |- + Creates and manages SAML Federation for Selectel products using public API v1. +--- + +# selectel\_iam\_saml\_federation\_v1 + +Manages SAML Federation for Selectel products using public API v1. +Selectel products support Identity and Access Management (IAM). +For more information about Federations, see the [official Selectel documentation](https://docs.selectel.ru/en/control-panel-actions/users-and-roles/federations/). + +## Example Usage + +```hcl +resource "selectel_iam_saml_federation_v1" "federation_1" { + name = "federation name" + description = "simple description" + issuer = "http://localhost:8080/realms/master" + sso_url = "http://localhost:8080/realms/master/protocol/saml" + sign_authn_requests = true + force_authn = true + session_max_age_hours = 24 +} +``` + +## Argument Reference + +* `name` - (Required) Federation name. + +* `description` - (Optional) Federation description. + +* `issuer` - (Required) ID of the credential provider. + +* `sso_url` - (Required) Link to the credential provider login page. + +* `sign_authn_requests` - (Required) Enable authentication requests signing. + +* `forec_authn` - (Optional) Require users to authenticate via SSO every time they log in. + +* `session_max_age_hours` - (Required) Session lifetime. + +## Attributes Reference + +* `account_id` - Federation account ID. + +## Import + +You can import a federation: + +```shell +export OS_DOMAIN_NAME= +export OS_USERNAME= +export OS_PASSWORD= +terraform import selectel_iam_saml_federation_v1.federation_1 +``` + +where: + +* `` — Selectel account ID. The account ID is in the top right corner of the [Control panel](https://my.selectel.ru/). Learn more about [Registration](https://docs.selectel.ru/en/control-panel-actions/account/registration/). + +* `` — Name of the service user. To get the name, in the [Control panel](https://my.selectel.ru/iam/users_management/users?type=service), go to **Identity & Access Management** ⟶ **User management** ⟶ the **Service users** tab ⟶ copy the name of the required user. Learn more about [Service Users](https://docs.selectel.ru/en/control-panel-actions/users-and-roles/user-types-and-roles/). + +* `` — Password of the service user. + +* `` — Unique identifier of the federation, for example, `abc1bb378ac84e1234b869b77aadd2ab`. To get the federation ID, use either [Control Panel](https://my.selectel.ru/iam/federations) or [IAM API](https://developers.selectel.ru/docs/control-panel/iam/). From e1151d1fab358deb7276c345d91572533ee59722 Mon Sep 17 00:00:00 2001 From: Icerzack Date: Mon, 29 Jul 2024 17:19:59 +0300 Subject: [PATCH 4/8] upd --- .github/workflows/secure.yml | 4 +++- .github/workflows/verify.yml | 4 +++- selectel/provider.go | 4 ---- .../resource_selectel_iam_s3_credentials_v1.go | 6 +++--- ...source_selectel_iam_s3_credentials_v1_test.go | 16 ++++++++-------- .../resource_selectel_iam_serviceuser_v1_test.go | 2 +- selectel/resource_selectel_iam_user_v1_test.go | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/secure.yml b/.github/workflows/secure.yml index 8b90e7d9..8570abb6 100644 --- a/.github/workflows/secure.yml +++ b/.github/workflows/secure.yml @@ -1,6 +1,8 @@ name: Secure -on: push +on: + push: + pull_request: jobs: # Sample GitHub Actions: diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 97da0b9d..935c18af 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -1,6 +1,8 @@ name: Verify -on: push +on: + push: + pull_request: jobs: tests: diff --git a/selectel/provider.go b/selectel/provider.go index d0114b0a..0e86d7a5 100644 --- a/selectel/provider.go +++ b/selectel/provider.go @@ -27,8 +27,6 @@ const ( objectUser = "user" objectServiceUser = "service user" objectS3Credentials = "s3 credentials" - objectGroup = "group" - objectGroupMembership = "group-membership" objectSAMLFederation = "saml federation" objectSAMLFederationCertificate = "saml federation certificate" objectCluster = "cluster" @@ -139,8 +137,6 @@ func Provider() *schema.Provider { "selectel_iam_serviceuser_v1": resourceIAMServiceUserV1(), "selectel_iam_user_v1": resourceIAMUserV1(), "selectel_iam_s3_credentials_v1": resourceIAMS3CredentialsV1(), - "selectel_iam_group_v1": resourceIAMGroupV1(), - "selectel_iam_group_membership_v1": resourceIAMGroupMembershipV1(), "selectel_iam_saml_federation_v1": resourceIAMSAMLFederationV1(), "selectel_iam_saml_federation_certificate_v1": resourceIAMSAMLFederationCertificateV1(), "selectel_vpc_vrrp_subnet_v2": resourceVPCVRRPSubnetV2(), // DEPRECATED diff --git a/selectel/resource_selectel_iam_s3_credentials_v1.go b/selectel/resource_selectel_iam_s3_credentials_v1.go index 0ba0d476..61e9dae8 100644 --- a/selectel/resource_selectel_iam_s3_credentials_v1.go +++ b/selectel/resource_selectel_iam_s3_credentials_v1.go @@ -90,13 +90,13 @@ func resourceIAMS3CredentialsV1Read(ctx context.Context, d *schema.ResourceData, } log.Print(msgGet(objectS3Credentials, d.Id())) - credentials, err := iamClient.S3Credentials.List(ctx, d.Get("user_id").(string)) + response, err := iamClient.S3Credentials.List(ctx, d.Get("user_id").(string)) if err != nil { return diag.FromErr(errGettingObject(objectS3Credentials, d.Id(), err)) } - var credential s3credentials.Credentials - for _, c := range credentials { + var credential s3credentials.Credential + for _, c := range response.Credentials { if d.Id() == c.AccessKey { credential = c break diff --git a/selectel/resource_selectel_iam_s3_credentials_v1_test.go b/selectel/resource_selectel_iam_s3_credentials_v1_test.go index 3ed967d2..a9be4275 100644 --- a/selectel/resource_selectel_iam_s3_credentials_v1_test.go +++ b/selectel/resource_selectel_iam_s3_credentials_v1_test.go @@ -13,7 +13,7 @@ import ( ) func TestAccIAMV1S3CredentialsBasic(t *testing.T) { - var s3credentials s3credentials.Credentials + var s3credential s3credentials.Credential s3CredsName := acctest.RandomWithPrefix("tf-acc") projectName := acctest.RandomWithPrefix("tf-acc") userName := acctest.RandomWithPrefix("tf-acc") @@ -27,7 +27,7 @@ func TestAccIAMV1S3CredentialsBasic(t *testing.T) { { Config: testAccIAMV1S3CredentialsBasic(projectName, userName, userPassword, s3CredsName), Check: resource.ComposeTestCheckFunc( - testAccCheckIAMV1S3CredentialsExists("selectel_iam_s3_credentials_v1.s3_creds_tf_acc_test_1", &s3credentials), + testAccCheckIAMV1S3CredentialsExists("selectel_iam_s3_credentials_v1.s3_creds_tf_acc_test_1", &s3credential), resource.TestCheckResourceAttrSet("selectel_iam_s3_credentials_v1.s3_creds_tf_acc_test_1", "user_id"), resource.TestCheckResourceAttrSet("selectel_iam_s3_credentials_v1.s3_creds_tf_acc_test_1", "project_id"), resource.TestCheckResourceAttrSet("selectel_iam_s3_credentials_v1.s3_creds_tf_acc_test_1", "secret_key"), @@ -50,8 +50,8 @@ func testAccCheckIAMV1S3CredentialsDestroy(s *terraform.State) error { continue } - credentialsList, _ := iamClient.S3Credentials.List(context.Background(), rs.Primary.Attributes["user_id"]) - for _, cred := range credentialsList { + response, _ := iamClient.S3Credentials.List(context.Background(), rs.Primary.Attributes["user_id"]) + for _, cred := range response.Credentials { if cred.AccessKey == rs.Primary.ID { return errors.New("s3 credentials still exist") } @@ -61,7 +61,7 @@ func testAccCheckIAMV1S3CredentialsDestroy(s *terraform.State) error { return nil } -func testAccCheckIAMV1S3CredentialsExists(n string, s3Credential *s3credentials.Credentials) resource.TestCheckFunc { +func testAccCheckIAMV1S3CredentialsExists(n string, s3Credential *s3credentials.Credential) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -77,9 +77,9 @@ func testAccCheckIAMV1S3CredentialsExists(n string, s3Credential *s3credentials. return fmt.Errorf("can't get iamclient for test s3 credentials object") } - credentialsList, _ := iamClient.S3Credentials.List(context.Background(), rs.Primary.Attributes["user_id"]) - var neededS3Credentials s3credentials.Credentials - for _, cred := range credentialsList { + response, _ := iamClient.S3Credentials.List(context.Background(), rs.Primary.Attributes["user_id"]) + var neededS3Credentials s3credentials.Credential + for _, cred := range response.Credentials { if cred.Name == rs.Primary.Attributes["name"] { neededS3Credentials = cred break diff --git a/selectel/resource_selectel_iam_serviceuser_v1_test.go b/selectel/resource_selectel_iam_serviceuser_v1_test.go index bec34bf8..5afd0a37 100644 --- a/selectel/resource_selectel_iam_serviceuser_v1_test.go +++ b/selectel/resource_selectel_iam_serviceuser_v1_test.go @@ -171,7 +171,7 @@ func testAccCheckIAMV1ServiceUserExists(n string, serviceUser *serviceusers.Serv return errors.New("serviceUser not found") } - *serviceUser = *su + *serviceUser = su.ServiceUser return nil } diff --git a/selectel/resource_selectel_iam_user_v1_test.go b/selectel/resource_selectel_iam_user_v1_test.go index e4058af1..e5f73592 100644 --- a/selectel/resource_selectel_iam_user_v1_test.go +++ b/selectel/resource_selectel_iam_user_v1_test.go @@ -123,7 +123,7 @@ func testAccCheckIAMV1UserExists(n string, user *users.User) resource.TestCheckF return errors.New("user not found") } - *user = *u + *user = u.User return nil } From 56387b71ff9e0a2a8eac99a9caabf051f531c8d1 Mon Sep 17 00:00:00 2001 From: Icerzack Date: Mon, 29 Jul 2024 17:40:47 +0300 Subject: [PATCH 5/8] upd --- .../resource_selectel_iam_saml_federation_certificate_v1.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go index 81787374..f5f23a04 100644 --- a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go @@ -27,6 +27,7 @@ func resourceIAMSAMLFederationCertificateV1() *schema.Resource { "federation_id": { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "Federation ID to create Certificate for.", }, "name": { @@ -43,6 +44,7 @@ func resourceIAMSAMLFederationCertificateV1() *schema.Resource { "data": { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "Certificate issued on the provider side. It must begin with -----BEGIN CERTIFICATE----- and end with -----END CERTIFICATE-----.", }, "account_id": { From b6f8dae63ce5b4d214ba1e23fdbaa7e5c9173c0b Mon Sep 17 00:00:00 2001 From: Icerzack Date: Wed, 31 Jul 2024 15:46:16 +0300 Subject: [PATCH 6/8] fix? --- ...selectel_iam_saml_federation_certificate_v1.go | 14 +++++++------- .../resource_selectel_iam_saml_federation_v1.go | 15 +++++++++------ .../docs/r/iam_saml_federation_v1.html.markdown | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go index f5f23a04..37d8af57 100644 --- a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go @@ -2,14 +2,12 @@ package selectel import ( "context" - "errors" "fmt" "log" "os" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/selectel/iam-go/iamerrors" "github.com/selectel/iam-go/service/federations/saml/certificates" ) @@ -77,17 +75,19 @@ func resourceIAMSAMLFederationCertificateV1Create(ctx context.Context, d *schema return diagErr } - log.Print(msgCreate(objectSAMLFederationCertificate, d.Id())) - federation, err := iamClient.SAMLFederations.Certificates.Create(ctx, d.Get("federation_id").(string), certificates.CreateRequest{ + opts := certificates.CreateRequest{ Name: d.Get("name").(string), Description: d.Get("description").(string), Data: d.Get("data").(string), - }) + } + log.Print(msgCreate(objectSAMLFederationCertificate, opts)) + + certificate, err := iamClient.SAMLFederations.Certificates.Create(ctx, d.Get("federation_id").(string), opts) if err != nil { return diag.FromErr(errCreatingObject(objectSAMLFederationCertificate, err)) } - d.SetId(federation.ID) + d.SetId(certificate.ID) return resourceIAMSAMLFederationCertificateV1Read(ctx, d, meta) } @@ -145,7 +145,7 @@ func resourceIAMSAMLFederationCertificateV1Delete(ctx context.Context, d *schema log.Print(msgDelete(objectSAMLFederationCertificate, d.Id())) err := iamClient.SAMLFederations.Certificates.Delete(ctx, d.Get("federation_id").(string), d.Id()) - if err != nil && !errors.Is(err, iamerrors.ErrFederationNotFound) { + if err != nil { return diag.FromErr(errDeletingObject(objectSAMLFederationCertificate, d.Id(), err)) } diff --git a/selectel/resource_selectel_iam_saml_federation_v1.go b/selectel/resource_selectel_iam_saml_federation_v1.go index de982b9e..d0eec7fd 100644 --- a/selectel/resource_selectel_iam_saml_federation_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_v1.go @@ -25,7 +25,7 @@ func resourceIAMSAMLFederationV1() *schema.Resource { "name": { Type: schema.TypeString, Required: true, - Description: "Name of the Federation", + Description: "Name of the Federation.", }, "description": { Type: schema.TypeString, @@ -36,7 +36,7 @@ func resourceIAMSAMLFederationV1() *schema.Resource { "issuer": { Type: schema.TypeString, Required: true, - Description: "IdP server endpoint URL.", + Description: "ID of the credential provider.", }, "sso_url": { Type: schema.TypeString, @@ -45,7 +45,8 @@ func resourceIAMSAMLFederationV1() *schema.Resource { }, "sign_authn_requests": { Type: schema.TypeBool, - Required: true, + Optional: true, + Default: false, Description: "Should sign authentication requests.", }, "session_max_age_hours": { @@ -74,8 +75,7 @@ func resourceIAMSAMLFederationV1Create(ctx context.Context, d *schema.ResourceDa return diagErr } - log.Print(msgCreate(objectSAMLFederation, d.Id())) - federation, err := iamClient.SAMLFederations.Create(ctx, saml.CreateRequest{ + opts := saml.CreateRequest{ Name: d.Get("name").(string), Description: d.Get("description").(string), Issuer: d.Get("issuer").(string), @@ -83,7 +83,10 @@ func resourceIAMSAMLFederationV1Create(ctx context.Context, d *schema.ResourceDa SignAuthnRequests: d.Get("sign_authn_requests").(bool), ForceAuthn: d.Get("force_authn").(bool), SessionMaxAgeHours: d.Get("session_max_age_hours").(int), - }) + } + log.Print(msgCreate(objectSAMLFederation, opts)) + + federation, err := iamClient.SAMLFederations.Create(ctx, opts) if err != nil { return diag.FromErr(errCreatingObject(objectSAMLFederation, err)) } diff --git a/website/docs/r/iam_saml_federation_v1.html.markdown b/website/docs/r/iam_saml_federation_v1.html.markdown index 36b14d98..5ab0c178 100644 --- a/website/docs/r/iam_saml_federation_v1.html.markdown +++ b/website/docs/r/iam_saml_federation_v1.html.markdown @@ -38,7 +38,7 @@ resource "selectel_iam_saml_federation_v1" "federation_1" { * `sign_authn_requests` - (Required) Enable authentication requests signing. -* `forec_authn` - (Optional) Require users to authenticate via SSO every time they log in. +* `force_authn` - (Optional) Require users to authenticate via SSO every time they log in. * `session_max_age_hours` - (Required) Session lifetime. From f4c17ce33a4239e1b2c93b4790c50509a55ac23e Mon Sep 17 00:00:00 2001 From: Icerzack Date: Wed, 31 Jul 2024 18:09:42 +0300 Subject: [PATCH 7/8] fix? --- website/docs/r/iam_saml_federation_v1.html.markdown | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/website/docs/r/iam_saml_federation_v1.html.markdown b/website/docs/r/iam_saml_federation_v1.html.markdown index 5ab0c178..7a76a799 100644 --- a/website/docs/r/iam_saml_federation_v1.html.markdown +++ b/website/docs/r/iam_saml_federation_v1.html.markdown @@ -20,8 +20,6 @@ resource "selectel_iam_saml_federation_v1" "federation_1" { description = "simple description" issuer = "http://localhost:8080/realms/master" sso_url = "http://localhost:8080/realms/master/protocol/saml" - sign_authn_requests = true - force_authn = true session_max_age_hours = 24 } ``` @@ -36,7 +34,7 @@ resource "selectel_iam_saml_federation_v1" "federation_1" { * `sso_url` - (Required) Link to the credential provider login page. -* `sign_authn_requests` - (Required) Enable authentication requests signing. +* `sign_authn_requests` - (Optional) Enable authentication requests signing. * `force_authn` - (Optional) Require users to authenticate via SSO every time they log in. From e6e8b3793070dc3b09aea85fdb56f6e93a4a1754 Mon Sep 17 00:00:00 2001 From: Icerzack Date: Thu, 1 Aug 2024 10:54:14 +0300 Subject: [PATCH 8/8] upd --- go.mod | 2 +- go.sum | 4 ++-- .../resource_selectel_iam_saml_federation_certificate_v1.go | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 83700a76..60bc76cd 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/selectel/dbaas-go v0.12.1 github.com/selectel/domains-go v1.0.2 github.com/selectel/go-selvpcclient/v3 v3.1.1 - github.com/selectel/iam-go v0.4.0 + github.com/selectel/iam-go v0.4.1 github.com/selectel/mks-go v0.14.0 github.com/selectel/secretsmanager-go v0.2.1 github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index 19d26790..85750867 100644 --- a/go.sum +++ b/go.sum @@ -170,8 +170,8 @@ github.com/selectel/domains-go v1.0.2 h1:Si6iGaMnTFJxwiJVI50DOdZnwcxc87kqaWrVQYW github.com/selectel/domains-go v1.0.2/go.mod h1:SugRKfq4sTpnOHquslCpzda72wV8u0cMBHx0C0l+bzA= github.com/selectel/go-selvpcclient/v3 v3.1.1 h1:C1q2LqqosiapoLpnGITGmysg0YCSQYDo2Gh69CioevM= github.com/selectel/go-selvpcclient/v3 v3.1.1/go.mod h1:NM7IXhh1IzqZ88DOw1Qc5Ez3tULLViXo95l5+rKPuyQ= -github.com/selectel/iam-go v0.4.0 h1:jlFUqSNt0NXO9BAP4MUpDg7pi+bncfWJ2eGDOkXMbo8= -github.com/selectel/iam-go v0.4.0/go.mod h1:OIAkW7MZK97YUm+uvUgYbgDhkI9SdzTCxwd4yZoOR1o= +github.com/selectel/iam-go v0.4.1 h1:grncCGkPVCM6nwqSTk+q15M5ZO6S/Pe0AIbbmKtm6gU= +github.com/selectel/iam-go v0.4.1/go.mod h1:OIAkW7MZK97YUm+uvUgYbgDhkI9SdzTCxwd4yZoOR1o= github.com/selectel/mks-go v0.14.0 h1:huNq/oTutPc3ezB8HRqlGN9WJubTDETpNKuIVqcZOn0= github.com/selectel/mks-go v0.14.0/go.mod h1:VxtV3dzwgOEzZc+9VMQb9DvxfSlej2ZQ8jnT8kqIGgU= github.com/selectel/secretsmanager-go v0.2.1 h1:OSBrA/07lm/Ecpwg59IJHFAoUHZR29oyfwUgTpr/dos= diff --git a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go index 37d8af57..7c6c2ed4 100644 --- a/selectel/resource_selectel_iam_saml_federation_certificate_v1.go +++ b/selectel/resource_selectel_iam_saml_federation_certificate_v1.go @@ -2,12 +2,14 @@ package selectel import ( "context" + "errors" "fmt" "log" "os" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/selectel/iam-go/iamerrors" "github.com/selectel/iam-go/service/federations/saml/certificates" ) @@ -145,7 +147,7 @@ func resourceIAMSAMLFederationCertificateV1Delete(ctx context.Context, d *schema log.Print(msgDelete(objectSAMLFederationCertificate, d.Id())) err := iamClient.SAMLFederations.Certificates.Delete(ctx, d.Get("federation_id").(string), d.Id()) - if err != nil { + if err != nil && !errors.Is(err, iamerrors.ErrFederationCertificateNotFound) { return diag.FromErr(errDeletingObject(objectSAMLFederationCertificate, d.Id(), err)) }