Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(container-registry): add OVHcloud IAM feature for Managed Registry #907

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/data-sources/cloud_project_containerregistry_iam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
subcategory : "Managed Private Registry (MPR)"
---

# ovh_cloud_project_containerregistry_iam (Data Source)

Use this data source to get a OVHcloud Managed Private Registry through OVHcloud IAM.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should rephrase this


## Example Usage

```hcl
data "ovh_cloud_project_containerregistry_iam" "my_iam" {
service_name = "XXXXXX"
registry_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
}

output "iam-enabled" {
value = data.ovh_cloud_project_containerregistry_iam.my_iam.iam_enabled
}
```

## Argument Reference

The following arguments are supported:

* `service_name` - (Optional) The id of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used.
* `registry_id` - The id of the Managed Private Registry.

## Attributes Reference

The following attributes are exported:

* `service_name` - The ID of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used.
* `registry_id` - The ID of the Managed Private Registry.
* `iam-enabled` - OVHcloud IAM feature status.
58 changes: 58 additions & 0 deletions docs/resources/cloud_project_containerregistry_iam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
subcategory : "Managed Private Registry (MPR)"
---

# ovh_cloud_project_containerregistry_iam

Creates an OVHcloud IAM configuration in an OVHcloud Managed Private Registry.

## Example Usage

```hcl
resource "ovh_cloud_project_containerregistry_iam" "my_iam" {
service_name = "XXXXXX"
registry_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"

#optional field
delete_users = false
}

output "iam-enabled" {
value = ovh_cloud_project_containerregistry_iam.my_iam.iam-enabled
sensitive = true
}
```

## Argument Reference

The following arguments are supported:

* `service_name` - The ID of the public cloud project. If omitted, the `OVH_CLOUD_PROJECT_SERVICE` environment variable is used. **Changing this value recreates the resource.**
* `registry_id` - The ID of the Managed Private Registry. **Changing this value recreates the resource.**
* `delete_users` - Delete existing users from Harbor. IAM feature can't be enabled if there is at least one user already created. This parameter is only used at IAM configuration creation. **Changing this value recreates the resource.**

## Timeouts

```hcl
resource "ovh_cloud_project_containerregistry_iam" "my-iam" {
# ...

timeouts {
create = "1h"
update = "45m"
delete = "50s"
}
}
```

* `create` - (Default 10m)
* `update` - (Default 10m)
* `delete` - (Default 10m)

## Import

OVHcloud Managed Private Registry OVHcloud IAM can be imported using the tenant `service_name` and registry id `registry_id` separated by "/" E.g.,

```bash
$ terraform import ovh_cloud_project_containerregistry_iam.my-iam service_name/registry_id
```
5 changes: 5 additions & 0 deletions ovh/data_cloud_project_containerregistries.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ func dataSourceCloudProjectContainerRegistries() *schema.Resource {
Description: "Registry creation date",
Computed: true,
},
"iam_enabled": {
Type: schema.TypeBool,
Description: "OVHcloud IAM enabled",
Computed: true,
},
"id": {
Type: schema.TypeString,
Description: "Registry ID",
Expand Down
5 changes: 5 additions & 0 deletions ovh/data_cloud_project_containerregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ func dataSourceCloudProjectContainerRegistry() *schema.Resource {
Description: "Registry creation date",
Computed: true,
},
"iam_enabled": {
Type: schema.TypeBool,
Description: "OVHcloud IAM enabled",
Computed: true,
},
"name": {
Type: schema.TypeString,
Description: "Registry name",
Expand Down
62 changes: 62 additions & 0 deletions ovh/data_cloud_project_containerregistry_iam.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package ovh

import (
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceCloudProjectContainerRegistryIAM() *schema.Resource {
return &schema.Resource{
Read: dataSourceCloudProjectContainerRegistryIAMRead,
Schema: map[string]*schema.Schema{
"service_name": {
Type: schema.TypeString,
Description: "Service name",
Required: true,
ForceNew: true,
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
},
"registry_id": {
Type: schema.TypeString,
Description: "Registry ID",
Required: true,
ForceNew: true,
},
"iam_enabled": {
Type: schema.TypeBool,
Description: "OVHcloud IAM enabled",
Computed: true,
},
},
}
}

func dataSourceCloudProjectContainerRegistryIAMRead(d *schema.ResourceData, meta any) error {
config := meta.(*Config)
serviceName := d.Get("service_name").(string)
registryID := d.Get("registry_id").(string)

endpoint := fmt.Sprintf("/cloud/project/%s/containerRegistry/%s", serviceName, registryID)
res := &CloudProjectContainerRegistry{}

log.Printf("[DEBUG] Will read from registry %s and project: %s", registryID, serviceName)

err := config.OVHClient.Get(endpoint, res)
if err != nil {
return fmt.Errorf("calling get %s %w", endpoint, err)
}

for k, v := range res.ToMap() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for k, v := range res.ToMap() {
for k, v := range res.ToMap() {

if k == "iam_enabled" {
d.Set(k, v)
}
}

d.SetId(serviceName + "/" + registryID)

log.Printf("[DEBUG] Read IAM %+v", res)

return nil
}
72 changes: 72 additions & 0 deletions ovh/data_cloud_project_containerregistry_iam_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package ovh

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAccCloudProjectContainerRegistryIAMDataSource_basic(t *testing.T) {
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")
region := os.Getenv("OVH_CLOUD_PROJECT_CONTAINERREGISTRY_REGION_TEST")
registryName := acctest.RandomWithPrefix(test_prefix)

config := fmt.Sprintf(
testAccCloudProjectContainerRegistryIAMDataSourceConfig,
serviceName,
region,
registryName,
)

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheckContainerRegistryIAM(t)
},
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"data.ovh_cloud_project_containerregistry_iam.iamData", "iam_enabled", "true"),
),
},
},
})
}

var testAccCloudProjectContainerRegistryIAMDataSourceConfig = `
data "ovh_cloud_project_capabilities_containerregistry_filter" "registryCap" {
service_name = "%s"
plan_name = "SMALL"
region = "%s"
}

resource "ovh_cloud_project_containerregistry" "registry" {
service_name = data.ovh_cloud_project_capabilities_containerregistry_filter.registryCap.service_name
plan_id = data.ovh_cloud_project_capabilities_containerregistry_filter.registryCap.id
name = "%s"
region = data.ovh_cloud_project_capabilities_containerregistry_filter.registryCap.region
}

resource "ovh_cloud_project_containerregistry_iam" "iam" {
service_name = ovh_cloud_project_containerregistry.registry.service_name
registry_id = ovh_cloud_project_containerregistry.registry.id

depends_on = [
ovh_cloud_project_containerregistry.registry
]
}

data "ovh_cloud_project_containerregistry_iam" "iamData" {
service_name = ovh_cloud_project_containerregistry.registry.service_name
registry_id = ovh_cloud_project_containerregistry.registry.id

depends_on = [
ovh_cloud_project_containerregistry_iam.iam
]
}
`
2 changes: 2 additions & 0 deletions ovh/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func Provider() *schema.Provider {
"ovh_cloud_project_containerregistries": dataSourceCloudProjectContainerRegistries(),
"ovh_cloud_project_containerregistry": dataSourceCloudProjectContainerRegistry(),
"ovh_cloud_project_containerregistry_oidc": dataSourceCloudProjectContainerRegistryOIDC(),
"ovh_cloud_project_containerregistry_iam": dataSourceCloudProjectContainerRegistryIAM(),
"ovh_cloud_project_containerregistry_users": dataSourceCloudProjectContainerRegistryUsers(),
"ovh_cloud_project_database": dataSourceCloudProjectDatabase(),
"ovh_cloud_project_databases": dataSourceCloudProjectDatabases(),
Expand Down Expand Up @@ -188,6 +189,7 @@ func Provider() *schema.Provider {
"ovh_cloud_project": resourceCloudProject(),
"ovh_cloud_project_containerregistry": resourceCloudProjectContainerRegistry(),
"ovh_cloud_project_containerregistry_oidc": resourceCloudProjectContainerRegistryOIDC(),
"ovh_cloud_project_containerregistry_iam": resourceCloudProjectContainerRegistryIAM(),
"ovh_cloud_project_containerregistry_user": resourceCloudProjectContainerRegistryUser(),
"ovh_cloud_project_containerregistry_ip_restrictions_management": resourceCloudProjectContainerRegistryIPRestrictionsManagement(),
"ovh_cloud_project_containerregistry_ip_restrictions_registry": resourceCloudProjectContainerRegistryIPRestrictionsRegistry(),
Expand Down
7 changes: 6 additions & 1 deletion ovh/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ func testAccPreCheckContainerRegistryOIDC(t *testing.T) {
checkEnvOrSkip(t, "OVH_CLOUD_PROJECT_CONTAINERREGISTRY_OIDC_ENDPOINT_TEST")
}

// Checks that the environment variables needed for the /cloud/{cloudId}/containerregistry/{registryID}/iam acceptance tests
// are set.
func testAccPreCheckContainerRegistryIAM(t *testing.T) {
testAccPreCheckContainerRegistry(t)
}

// Checks that the environment variables needed for the /cloud/project/{projectId}/network/private/ acceptance tests are set.
func testAccPreCheckCloudNetworkPrivate(t *testing.T) {
testAccPreCheckCloud(t)
Expand Down Expand Up @@ -485,7 +491,6 @@ func testAccCheckDomainZoneExists(t *testing.T) {
}

t.Logf("Read Domain Zone %s -> nameservers: '%v'", endpoint, r.NameServers)

}

func testAccPreCheckDedicatedCeph(t *testing.T) {
Expand Down
5 changes: 5 additions & 0 deletions ovh/resource_cloud_project_containerregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ func resourceCloudProjectContainerRegistry() *schema.Resource {
Description: "Registry creation date",
Computed: true,
},
"iam_enabled": {
Type: schema.TypeBool,
Description: "OVHcloud IAM enabled",
Computed: true,
},
"project_id": {
Type: schema.TypeString,
Description: "Project ID of your registry",
Expand Down
Loading