diff --git a/bigip/datasource_bigip_role_info.go b/bigip/datasource_bigip_role_info.go new file mode 100644 index 00000000..245ad7bf --- /dev/null +++ b/bigip/datasource_bigip_role_info.go @@ -0,0 +1,94 @@ +/* +Copyright 2019 F5 Networks Inc. +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ +package bigip + +import ( + "context" + "fmt" + "log" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceBigipRoleInfo() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceBigipRoleInfoRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name of the role info", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "The description of the role info", + }, + "attribute": { + Type: schema.TypeString, + Required: true, + Description: "The attribute of the role info", + }, + "console": { + Type: schema.TypeString, + Optional: true, + Description: "The console of the role info", + }, + "deny": { + Type: schema.TypeString, + Optional: true, + Description: "The deny of the role info", + }, + "role": { + Type: schema.TypeString, + Optional: true, + Description: "The role of the role info", + }, + "user_partition": { + Type: schema.TypeString, + Optional: true, + Description: "The user partition of the role info", + }, + "line_order": { + Type: schema.TypeInt, + Required: true, + Description: "The line order of the role info", + }, + }, + } +} + +func dataSourceBigipRoleInfoRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Get("name").(string) + + roleInfo, err := client.GetRoleInfo(name) + if err != nil { + return diag.FromErr(fmt.Errorf("error retrieving Role Info %s: %v ", name, err)) + } + if roleInfo == nil { + log.Printf("[DEBUG] Role Info (%s) not found, removing from state", name) + d.SetId("") + return nil + } + + _ = d.Set("name", roleInfo.Name) + _ = d.Set("attribute", roleInfo.Attribute) + _ = d.Set("console", roleInfo.Console) + _ = d.Set("deny", roleInfo.Deny) + _ = d.Set("description", roleInfo.Description) + _ = d.Set("line-order", roleInfo.LineOrder) + _ = d.Set("role", roleInfo.Role) + _ = d.Set("user-partition", roleInfo.UserPartition) + + d.SetId(roleInfo.Name) + + return nil + +} diff --git a/bigip/provider.go b/bigip/provider.go index 17f4dba3..02e7dcc5 100644 --- a/bigip/provider.go +++ b/bigip/provider.go @@ -123,6 +123,7 @@ func Provider() *schema.Provider { "bigip_fast_aws_service_discovery": dataSourceBigipFastAwsServiceDiscovery(), "bigip_fast_azure_service_discovery": dataSourceBigipFastAzureServiceDiscovery(), "bigip_fast_gce_service_discovery": dataSourceBigipFastGceServiceDiscovery(), + "bigip_role_info": dataSourceBigipRoleInfo(), }, ResourcesMap: map[string]*schema.Resource{ "bigip_cm_device": resourceBigipCmDevice(), @@ -193,6 +194,7 @@ func Provider() *schema.Provider { "bigip_ltm_profile_bot_defense": resourceBigipLtmProfileBotDefense(), "bigip_ltm_profile_rewrite": resourceBigipLtmRewriteProfile(), "bigip_ltm_profile_rewrite_uri_rules": resourceBigipLtmRewriteProfileUriRules(), + "bigip_role_info": resourceBigipRoleInfo(), }, } p.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { diff --git a/bigip/resource_bigip_role_info.go b/bigip/resource_bigip_role_info.go new file mode 100644 index 00000000..e22ba9ca --- /dev/null +++ b/bigip/resource_bigip_role_info.go @@ -0,0 +1,163 @@ +package bigip + +import ( + "context" + "log" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceBigipRoleInfo() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBigipRoleInfoCreate, + ReadContext: resourceBigipRoleInfoRead, + UpdateContext: resourceBigipRoleInfoUpdate, + DeleteContext: resourceBigipRoleInfoDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name of the role info", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "The description of the role info", + }, + "attribute": { + Type: schema.TypeString, + Required: true, + Description: "The attribute of the role info", + }, + "console": { + Type: schema.TypeString, + Optional: true, + Description: "The console of the role info", + }, + "deny": { + Type: schema.TypeString, + Optional: true, + Description: "The deny of the role info", + }, + "role": { + Type: schema.TypeString, + Optional: true, + Description: "The role of the role info", + }, + "user_partition": { + Type: schema.TypeString, + Optional: true, + Description: "The user partition of the role info", + }, + "line_order": { + Type: schema.TypeInt, + Required: true, + Description: "The line order of the role info", + }, + }, + } +} + +func resourceBigipRoleInfoCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(*bigip.BigIP) + name := d.Get("name").(string) + attribute := d.Get("attribute").(string) + console := d.Get("console").(string) + deny := d.Get("deny").(string) + description := d.Get("description").(string) + lineOrder := d.Get("line_order").(int) + role := d.Get("role").(string) + userPartition := d.Get("user_partition").(string) + + roleInfo := &bigip.RoleInfo{ + Name: name, + Attribute: attribute, + Console: console, + Deny: deny, + Description: description, + LineOrder: lineOrder, + Role: role, + UserPartition: userPartition, + } + + err := client.CreateRoleInfo(roleInfo) + + if err != nil { + log.Printf("[ERROR] error while creating the role info: %s", name) + return diag.FromErr(err) + } + + d.SetId(name) + return resourceBigipRoleInfoRead(ctx, d, m) +} + +func resourceBigipRoleInfoRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(*bigip.BigIP) + name := d.Id() + roleInfo, err := client.GetRoleInfo(name) + + if err != nil { + log.Printf("[ERROR] error while reading the role info: %s", name) + return diag.FromErr(err) + } + + log.Printf("[INFO] Role Info: %+v", roleInfo) + d.Set("name", roleInfo.Name) + d.Set("attribute", roleInfo.Attribute) + d.Set("console", roleInfo.Console) + d.Set("deny", roleInfo.Deny) + d.Set("description", roleInfo.Description) + d.Set("line-order", roleInfo.LineOrder) + d.Set("role", roleInfo.Role) + d.Set("user-partition", roleInfo.UserPartition) + + return nil +} + +func resourceBigipRoleInfoUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + client := m.(*bigip.BigIP) + name := d.Id() + attribute := d.Get("attribute").(string) + console := d.Get("console").(string) + deny := d.Get("deny").(string) + description := d.Get("description").(string) + lineOrder := d.Get("line_order").(int) + role := d.Get("role").(string) + userPartition := d.Get("user_partition").(string) + + roleInfo := &bigip.RoleInfo{ + Name: name, + Attribute: attribute, + Console: console, + Deny: deny, + Description: description, + LineOrder: lineOrder, + Role: role, + UserPartition: userPartition, + } + err := client.ModifyRoleInfo(name, roleInfo) + + if err != nil { + log.Printf("[ERROR] error while updating the role info: %s", name) + return diag.FromErr(err) + } + + return resourceBigipRoleInfoRead(ctx, d, m) +} + +func resourceBigipRoleInfoDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + name := d.Id() + client := m.(*bigip.BigIP) + err := client.DeleteRoleInfo(name) + if err != nil { + log.Printf("[ERROR] error while deleting the role info: %s", name) + return diag.FromErr(err) + } + return nil +} diff --git a/bigip/resource_bigip_role_info_test.go b/bigip/resource_bigip_role_info_test.go new file mode 100644 index 00000000..e0850fbb --- /dev/null +++ b/bigip/resource_bigip_role_info_test.go @@ -0,0 +1,76 @@ +package bigip + +import ( + "testing" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +var TEST_ROLE_INFO_NAME = "test-roleinfo" +var TEST_ROLE_INFO_RESOURCE_1 = ` +resource "bigip_role_info" "test-roleinfo" { + name = "` + TEST_ROLE_INFO_NAME + `" + description = "created by teraform" + attribute = "attribute" + console = "console" + deny = "deny" + role = "role" + user_partition = "user_partition" + line_order = 1 +}` + +func TestAccRoleInfoCreateUpdate(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckRoleInfoDestroyed, + Steps: []resource.TestStep{ + { + Config: TEST_ROLE_INFO_RESOURCE_1, + Destroy: false, + Check: resource.ComposeTestCheckFunc( + testCheckRoleInfoExists(TEST_ROLE_INFO_NAME), + resource.TestCheckResourceAttr("bigip_role_info.test-roleinfo", "name", TEST_ROLE_INFO_NAME), + resource.TestCheckResourceAttr("bigip_role_info.test-roleinfo", "description", "created by teraform"), + resource.TestCheckResourceAttr("bigip_role_info.test-roleinfo", "attribute", "attribute"), + resource.TestCheckResourceAttr("bigip_role_info.test-roleinfo", "console", "console"), + resource.TestCheckResourceAttr("bigip_role_info.test-roleinfo", "deny", "deny"), + resource.TestCheckResourceAttr("bigip_role_info.test-roleinfo", "role", "role"), + resource.TestCheckResourceAttr("bigip_role_info.test-roleinfo", "user_partition", "user_partition"), + ), + }, + }, + }) +} + +func testCheckRoleInfoExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + roleInfo, err := client.GetRoleInfo(name) + if err != nil { + return err + } + if roleInfo.Name != name { + return err + } + return nil + } +} + +func testCheckRoleInfoDestroyed(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + for _, rs := range s.RootModule().Resources { + if rs.Type != "bigip_role_info" { + continue + } + _, err := client.GetRoleInfo(rs.Primary.ID) + if err == nil { + return err + } + } + return nil +} diff --git a/go.mod b/go.mod index d2853e26..a0557f13 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ module github.com/F5Networks/terraform-provider-bigip +replace github.com/f5devcentral/go-bigip => github.com/roberto-belardo/go-bigip v1.0.0 + require ( github.com/Azure/azure-sdk-for-go v53.4.0+incompatible github.com/Azure/azure-storage-blob-go v0.13.0 diff --git a/go.sum b/go.sum index 8131850f..62a224dc 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= -github.com/f5devcentral/go-bigip v0.0.0-20240214135103-fd95be9ae1fb h1:r2hm89TgbKAJQnViwet98Z7Hq1o5JE4TX/bbRG7489o= -github.com/f5devcentral/go-bigip v0.0.0-20240214135103-fd95be9ae1fb/go.mod h1:0Lkr0fBU6O1yBxF2mt9JFwXpaFbIb/wAY7oM3dMJDdA= github.com/f5devcentral/go-bigip/f5teem v0.0.0-20240214135103-fd95be9ae1fb h1:ZobhcJVa43SKFAhDUc3FQBnn5U+OXdAD7ur5lKbokIY= github.com/f5devcentral/go-bigip/f5teem v0.0.0-20240214135103-fd95be9ae1fb/go.mod h1:r7o5I22EvO+fps2u10bz4ZUlTlNHopQSWzVcW19hK3U= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -191,6 +189,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/roberto-belardo/go-bigip v1.0.0 h1:6o2cKPxaduJtwNGCMVWTsVTHAZBjtdZc588V49r6Pls= +github.com/roberto-belardo/go-bigip v1.0.0/go.mod h1:0Lkr0fBU6O1yBxF2mt9JFwXpaFbIb/wAY7oM3dMJDdA= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= diff --git a/vendor/github.com/f5devcentral/go-bigip/sys.go b/vendor/github.com/f5devcentral/go-bigip/sys.go index 66288431..9813f16e 100644 --- a/vendor/github.com/f5devcentral/go-bigip/sys.go +++ b/vendor/github.com/f5devcentral/go-bigip/sys.go @@ -298,6 +298,8 @@ const ( uriAvr = "avr" uriAuth = "auth" uriPartition = "partition" + uriRemoteRole = "remote-role" + uriRoleInfo = "role-info" uriFolder = "folder" uriIlx = "ilx" uriSyslog = "syslog" @@ -416,6 +418,17 @@ type Partition struct { Description string `json:"description,omitempty"` } +type RoleInfo struct { + Name string `json:"name,omitempty"` + Attribute string `json:"attribute"` + Console string `json:"console,omitempty"` + Deny string `json:"deny,omitempty"` + Description string `json:"description,omitempty"` + LineOrder int `json:"lineOrder"` + Role string `json:"role,omitempty"` + UserPartition string `json:"userPartition,omitempty"` +} + // Certificates returns a list of certificates. func (b *BigIP) Certificates() (*Certificates, error) { var certs Certificates @@ -1030,7 +1043,7 @@ func (b *BigIP) UploadDataGroupFile(f *os.File, tmpName string) (*Upload, error) return nil, err } log.Printf("tmpName:%+v", tmpName) - return b.Upload(f, info.Size(), uriShared, uriFileTransfer, uriUploads, fmt.Sprintf("%s", tmpName)) + return b.Upload(f, info.Size(), uriShared, uriFileTransfer, uriUploads, tmpName) } func (b *BigIP) CreateOCSP(ocsp *OCSP) error { @@ -1097,3 +1110,30 @@ func (b *BigIP) ModifyFolderDescription(partition string, body map[string]string partition = fmt.Sprintf("~%s", partition) return b.patch(body, uriSys, uriFolder, partition) } + +func (b *BigIP) CreateRoleInfo(roleInfo *RoleInfo) error { + return b.post(roleInfo, uriAuth, uriRemoteRole, uriRoleInfo) +} + +func (b *BigIP) GetRoleInfo(name string) (*RoleInfo, error) { + var roleInfo RoleInfo + err, ok := b.getForEntity(&roleInfo, uriAuth, uriRemoteRole, uriRoleInfo, name) + + if err != nil { + return nil, err + } + + if !ok { + return nil, nil + } + + return &roleInfo, err +} + +func (b *BigIP) ModifyRoleInfo(name string, roleInfo *RoleInfo) error { + return b.patch(roleInfo, uriAuth, uriRemoteRole, uriRoleInfo, name) +} + +func (b *BigIP) DeleteRoleInfo(name string) error { + return b.delete(uriAuth, uriRemoteRole, uriRoleInfo, name) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 9ac77032..96b12a24 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,7 +42,7 @@ github.com/apparentlymart/go-textseg/v13/textseg # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/f5devcentral/go-bigip v0.0.0-20240214135103-fd95be9ae1fb +# github.com/f5devcentral/go-bigip v0.0.0-20240214135103-fd95be9ae1fb => github.com/roberto-belardo/go-bigip v1.0.0 ## explicit; go 1.20 github.com/f5devcentral/go-bigip # github.com/f5devcentral/go-bigip/f5teem v0.0.0-20240214135103-fd95be9ae1fb @@ -398,3 +398,4 @@ google.golang.org/protobuf/types/known/timestamppb # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 +# github.com/f5devcentral/go-bigip => github.com/roberto-belardo/go-bigip v1.0.0