diff --git a/docs/data-sources/feeds.md b/docs/data-sources/feeds.md index 136a115ee..34f7fd34b 100644 --- a/docs/data-sources/feeds.md +++ b/docs/data-sources/feeds.md @@ -6,7 +6,7 @@ description: |- Provides information about existing feeds. --- -# Data Source `octopusdeploy_feeds` +# octopusdeploy_feeds (Data Source) Provides information about existing feeds. @@ -24,25 +24,25 @@ Provides information about existing feeds. - **skip** (Number) A filter to specify the number of items to skip in the response. - **take** (Number) A filter to specify the number of items to take (or return) in the response. -### Read-only +### Read-Only - **feeds** (Block List) A list of feeds that match the filter(s). (see [below for nested schema](#nestedblock--feeds)) ### Nested Schema for `feeds` -Read-only: +Read-Only: - **access_key** (String) - **api_version** (String) - **delete_unreleased_packages_after_days** (Number) -- **download_attempts** (Number) -- **download_retry_backoff_seconds** (Number) +- **download_attempts** (Number) The number of times a deployment should attempt to download a package from this feed before failing. +- **download_retry_backoff_seconds** (Number) The number of seconds to apply as a linear back off between download attempts. - **feed_type** (String) - **feed_uri** (String) - **id** (String) The unique ID for this resource. - **is_enhanced_mode** (Boolean) -- **name** (String) The name of this resource. +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. - **package_acquisition_location_options** (List of String) - **password** (String, Sensitive) The password associated with this resource. - **region** (String) diff --git a/docs/resources/aws_elastic_container_registry.md b/docs/resources/aws_elastic_container_registry.md new file mode 100644 index 000000000..a7d1d61bb --- /dev/null +++ b/docs/resources/aws_elastic_container_registry.md @@ -0,0 +1,45 @@ +--- +page_title: "Resource octopusdeploy_aws_elastic_container_registry - terraform-provider-octopusdeploy" +subcategory: "Feeds" +description: |- + This resource manages a AWS Elastic Container Registry in Octopus Deploy. +--- + +# Resource (octopusdeploy_aws_elastic_container_registry) + +This resource manages a AWS Elastic Container Registry in Octopus Deploy. + +## Example Usage + +```terraform +resource "octopusdeploy_aws_elastic_container_registry" "example" { + access_key = "AKIAIOSFODNN7EXAMPLE" + name = "Test AWS Elastic Container Registry (OK to Delete)" + region = "us-east-1" + secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" +} +``` + + +## Schema + +### Required + +- **access_key** (String) The AWS access key to use when authenticating against Amazon Web Services. +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. +- **region** (String) The AWS region where the registry resides. +- **secret_key** (String, Sensitive) The AWS secret key to use when authenticating against Amazon Web Services. + +### Optional + +- **id** (String) The unique ID for this feed. +- **package_acquisition_location_options** (List of String) +- **space_id** (String) The space ID associated with this feed. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import [options] octopusdeploy_aws_elastic_container_registry. +``` \ No newline at end of file diff --git a/docs/resources/docker_container_registry.md b/docs/resources/docker_container_registry.md new file mode 100644 index 000000000..1962b335f --- /dev/null +++ b/docs/resources/docker_container_registry.md @@ -0,0 +1,48 @@ +--- +page_title: "Resource octopusdeploy_docker_container_registry - terraform-provider-octopusdeploy" +subcategory: "Feeds" +description: |- + This resource manages a Docker Container Registry in Octopus Deploy. +--- + +# Resource (octopusdeploy_docker_container_registry) + +This resource manages a Docker Container Registry in Octopus Deploy. + +## Example Usage + +```terraform +resource "octopusdeploy_docker_container_registry" "example" { + feed_uri = "https://index.docker.io" + name = "Test Docker Container Registry (OK to Delete)" + password = "test-password" + registry_path = "testing/test-image" + username = "test-username" +} +``` + + +## Schema + +### Required + +- **feed_uri** (String) The URL to a Maven repository. This URL is the same value defined in the `repositories`/`repository`/`url` element of a Maven `settings.xml` file. +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. + +### Optional + +- **api_version** (String) +- **id** (String) The unique ID for this resource. +- **package_acquisition_location_options** (List of String) +- **password** (String, Sensitive) The password associated with this resource. +- **registry_path** (String) +- **space_id** (String) The space ID associated with this resource. +- **username** (String, Sensitive) The username associated with this resource. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import [options] octopusdeploy_docker_container_registry. +``` \ No newline at end of file diff --git a/docs/resources/feed.md b/docs/resources/feed.md index 5bfac9bc5..77772a564 100644 --- a/docs/resources/feed.md +++ b/docs/resources/feed.md @@ -1,16 +1,28 @@ --- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "octopusdeploy_feed Resource - terraform-provider-octopusdeploy" -subcategory: "" +page_title: "Resource octopusdeploy_feed - terraform-provider-octopusdeploy" +subcategory: "Feeds" description: |- --- -# Resource `octopusdeploy_feed` +# Resource (octopusdeploy_feed) +## Example Usage +```terraform +resource "octopusdeploy_feed" "example" { + download_attempts = 10 + download_retry_backoff_seconds = 60 + feed_uri = "https://repo.maven.apache.org/maven2/" + name = "Test Maven Feed (OK to Delete)" + package_acquisition_location_options = ["Server", "ExecutionTarget"] + password = "password123" + space_id = "Spaces-123" + username = "john.smith@example.com" +} +``` ## Schema @@ -18,15 +30,15 @@ description: |- ### Required - **feed_uri** (String) -- **name** (String) The name of this resource. +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. ### Optional - **access_key** (String) - **api_version** (String) - **delete_unreleased_packages_after_days** (Number) -- **download_attempts** (Number) -- **download_retry_backoff_seconds** (Number) +- **download_attempts** (Number) The number of times a deployment should attempt to download a package from this feed before failing. +- **download_retry_backoff_seconds** (Number) The number of seconds to apply as a linear back off between download attempts. - **feed_type** (String) - **id** (String) The unique ID for this resource. - **is_enhanced_mode** (Boolean) @@ -37,8 +49,14 @@ description: |- - **space_id** (String) The space ID associated with this resource. - **username** (String, Sensitive) The username associated with this resource. -### Read-only +### Read-Only - **region** (String) +## Import +Import is supported using the following syntax: + +```shell +terraform import [options] octopusdeploy_feed. +``` \ No newline at end of file diff --git a/docs/resources/github_repository_feed.md b/docs/resources/github_repository_feed.md new file mode 100644 index 000000000..a8cdadf0d --- /dev/null +++ b/docs/resources/github_repository_feed.md @@ -0,0 +1,49 @@ +--- +page_title: "Resource octopusdeploy_github_repository_feed - terraform-provider-octopusdeploy" +subcategory: "Feeds" +description: |- + This resource manages a GitHub repository feed in Octopus Deploy. +--- + +# Resource (octopusdeploy_github_repository_feed) + +This resource manages a GitHub repository feed in Octopus Deploy. + +## Example Usage + +```terraform +resource "octopusdeploy_github_repository_feed" "example" { + download_attempts = 1 + download_retry_backoff_seconds = 30 + feed_uri = "https://api.github.com" + password = "test-password" + name = "Test GitHub Repository Feed (OK to Delete)" + username = "test-username" +} +``` + + +## Schema + +### Required + +- **feed_uri** (String) +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. + +### Optional + +- **download_attempts** (Number) The number of times a deployment should attempt to download a package from this feed before failing. +- **download_retry_backoff_seconds** (Number) The number of seconds to apply as a linear back off between download attempts. +- **id** (String) The unique ID for this resource. +- **package_acquisition_location_options** (List of String) +- **password** (String, Sensitive) The password associated with this resource. +- **space_id** (String) The space ID associated with this resource. +- **username** (String, Sensitive) The username associated with this resource. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import [options] octopusdeploy_github_repository_feed. +``` \ No newline at end of file diff --git a/docs/resources/helm_feed.md b/docs/resources/helm_feed.md new file mode 100644 index 000000000..9306dc58d --- /dev/null +++ b/docs/resources/helm_feed.md @@ -0,0 +1,45 @@ +--- +page_title: "Resource octopusdeploy_helm_feed - terraform-provider-octopusdeploy" +subcategory: "Feeds" +description: |- + This resource manages a Helm feed in Octopus Deploy. +--- + +# Resource (octopusdeploy_helm_feed) + +This resource manages a Helm feed in Octopus Deploy. + +## Example Usage + +```terraform +resource "octopusdeploy_helm_feed" "example" { + feed_uri = "https://charts.helm.sh/stable" + password = "test-password" + name = "Test Helm Feed (OK to Delete)" + username = "test-username" +} +``` + + +## Schema + +### Required + +- **feed_uri** (String) +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. + +### Optional + +- **id** (String) The unique ID for this resource. +- **package_acquisition_location_options** (List of String) +- **password** (String, Sensitive) The password associated with this resource. +- **space_id** (String) The space ID associated with this resource. +- **username** (String, Sensitive) The username associated with this resource. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import [options] octopusdeploy_helm_feed. +``` \ No newline at end of file diff --git a/docs/resources/maven_feed.md b/docs/resources/maven_feed.md new file mode 100644 index 000000000..f7db60f9b --- /dev/null +++ b/docs/resources/maven_feed.md @@ -0,0 +1,51 @@ +--- +page_title: "Resource octopusdeploy_maven_feed - terraform-provider-octopusdeploy" +subcategory: "Feeds" +description: |- + This resource manages a Maven feed in Octopus Deploy. +--- + +# Resource (octopusdeploy_maven_feed) + +This resource manages a Maven feed in Octopus Deploy. + +## Example Usage + +```terraform +resource "octopusdeploy_maven_feed" "example" { + download_attempts = 10 + download_retry_backoff_seconds = 60 + feed_uri = "https://repo.maven.apache.org/maven2/" + name = "Test Maven Feed (OK to Delete)" + package_acquisition_location_options = ["Server", "ExecutionTarget"] + password = "password123" + space_id = "Spaces-123" + username = "john.smith@example.com" +} +``` + + +## Schema + +### Required + +- **feed_uri** (String) +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. + +### Optional + +- **download_attempts** (Number) The number of times a deployment should attempt to download a package from this feed before failing. +- **download_retry_backoff_seconds** (Number) The number of seconds to apply as a linear back off between download attempts. +- **id** (String) The unique ID for this resource. +- **package_acquisition_location_options** (List of String) +- **password** (String, Sensitive) The password associated with this resource. +- **space_id** (String) The space ID associated with this resource. +- **username** (String, Sensitive) The username associated with this resource. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import [options] octopusdeploy_maven_feed. +``` \ No newline at end of file diff --git a/docs/resources/nuget_feed.md b/docs/resources/nuget_feed.md index de1c5ecfb..d800d5dd3 100644 --- a/docs/resources/nuget_feed.md +++ b/docs/resources/nuget_feed.md @@ -1,32 +1,51 @@ --- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "octopusdeploy_nuget_feed Resource - terraform-provider-octopusdeploy" -subcategory: "" +page_title: "Resource octopusdeploy_nuget_feed - terraform-provider-octopusdeploy" +subcategory: "Feeds" description: |- - + This resource manages a NuGet feed in Octopus Deploy. --- -# Resource `octopusdeploy_nuget_feed` - +# Resource (octopusdeploy_nuget_feed) +This resource manages a NuGet feed in Octopus Deploy. +## Example Usage +```terraform +resource "octopusdeploy_nuget_feed" "example" { + download_attempts = 1 + download_retry_backoff_seconds = 30 + feed_uri = "https://api.nuget.org/v3/index.json" + is_enhanced_mode = true + password = "test-password" + name = "Test NuGet Feed (OK to Delete)" + username = "test-username" +} +``` ## Schema ### Required -- **feed_uri** (String) -- **name** (String) The name of this resource. +- **feed_uri** (String) The feed URI can be a URL or a folder path. +- **name** (String) A short, memorable, unique name for this feed. Example: ACME Builds. ### Optional -- **download_attempts** (Number) -- **download_retry_backoff_seconds** (Number) -- **id** (String) The ID of this resource. -- **is_enhanced_mode** (Boolean) +- **download_attempts** (Number) The number of times a deployment should attempt to download a package from this feed before failing. +- **download_retry_backoff_seconds** (Number) The number of seconds to apply as a linear back off between download attempts. +- **id** (String) The unique ID for this resource. +- **is_enhanced_mode** (Boolean) This will improve performance of the NuGet feed but may not be supported by some older feeds. Disable if the operation, Create Release does not return the latest version for a package. +- **package_acquisition_location_options** (List of String) - **password** (String, Sensitive) The password associated with this resource. +- **space_id** (String) The space ID associated with this resource. - **username** (String, Sensitive) The username associated with this resource. +## Import + +Import is supported using the following syntax: +```shell +terraform import [options] octopusdeploy_nuget_feed. +``` \ No newline at end of file diff --git a/examples/resources/octopusdeploy_aws_elastic_container_registry/import.sh b/examples/resources/octopusdeploy_aws_elastic_container_registry/import.sh new file mode 100644 index 000000000..28830953d --- /dev/null +++ b/examples/resources/octopusdeploy_aws_elastic_container_registry/import.sh @@ -0,0 +1 @@ +terraform import [options] octopusdeploy_aws_elastic_container_registry. \ No newline at end of file diff --git a/examples/resources/octopusdeploy_aws_elastic_container_registry/resource.tf b/examples/resources/octopusdeploy_aws_elastic_container_registry/resource.tf new file mode 100644 index 000000000..f51760512 --- /dev/null +++ b/examples/resources/octopusdeploy_aws_elastic_container_registry/resource.tf @@ -0,0 +1,6 @@ +resource "octopusdeploy_aws_elastic_container_registry" "example" { + access_key = "AKIAIOSFODNN7EXAMPLE" + name = "Test AWS Elastic Container Registry (OK to Delete)" + region = "us-east-1" + secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" +} diff --git a/examples/resources/octopusdeploy_docker_container_registry/import.sh b/examples/resources/octopusdeploy_docker_container_registry/import.sh new file mode 100644 index 000000000..555fe16cb --- /dev/null +++ b/examples/resources/octopusdeploy_docker_container_registry/import.sh @@ -0,0 +1 @@ +terraform import [options] octopusdeploy_docker_container_registry. \ No newline at end of file diff --git a/examples/resources/octopusdeploy_docker_container_registry/resource.tf b/examples/resources/octopusdeploy_docker_container_registry/resource.tf new file mode 100644 index 000000000..2f73c389a --- /dev/null +++ b/examples/resources/octopusdeploy_docker_container_registry/resource.tf @@ -0,0 +1,7 @@ +resource "octopusdeploy_docker_container_registry" "example" { + feed_uri = "https://index.docker.io" + name = "Test Docker Container Registry (OK to Delete)" + password = "test-password" + registry_path = "testing/test-image" + username = "test-username" +} diff --git a/examples/resources/octopusdeploy_feed/import.sh b/examples/resources/octopusdeploy_feed/import.sh new file mode 100644 index 000000000..2c61b7cb0 --- /dev/null +++ b/examples/resources/octopusdeploy_feed/import.sh @@ -0,0 +1 @@ +terraform import [options] octopusdeploy_feed. \ No newline at end of file diff --git a/examples/resources/octopusdeploy_feed/resource.tf b/examples/resources/octopusdeploy_feed/resource.tf new file mode 100644 index 000000000..16e3a548b --- /dev/null +++ b/examples/resources/octopusdeploy_feed/resource.tf @@ -0,0 +1,10 @@ +resource "octopusdeploy_feed" "example" { + download_attempts = 10 + download_retry_backoff_seconds = 60 + feed_uri = "https://repo.maven.apache.org/maven2/" + name = "Test Maven Feed (OK to Delete)" + package_acquisition_location_options = ["Server", "ExecutionTarget"] + password = "password123" + space_id = "Spaces-123" + username = "john.smith@example.com" +} \ No newline at end of file diff --git a/examples/resources/octopusdeploy_github_repository_feed/import.sh b/examples/resources/octopusdeploy_github_repository_feed/import.sh new file mode 100644 index 000000000..86000e325 --- /dev/null +++ b/examples/resources/octopusdeploy_github_repository_feed/import.sh @@ -0,0 +1 @@ +terraform import [options] octopusdeploy_github_repository_feed. \ No newline at end of file diff --git a/examples/resources/octopusdeploy_github_repository_feed/resource.tf b/examples/resources/octopusdeploy_github_repository_feed/resource.tf new file mode 100644 index 000000000..65f1205b7 --- /dev/null +++ b/examples/resources/octopusdeploy_github_repository_feed/resource.tf @@ -0,0 +1,8 @@ +resource "octopusdeploy_github_repository_feed" "example" { + download_attempts = 1 + download_retry_backoff_seconds = 30 + feed_uri = "https://api.github.com" + password = "test-password" + name = "Test GitHub Repository Feed (OK to Delete)" + username = "test-username" +} diff --git a/examples/resources/octopusdeploy_helm_feed/import.sh b/examples/resources/octopusdeploy_helm_feed/import.sh new file mode 100644 index 000000000..6346018b2 --- /dev/null +++ b/examples/resources/octopusdeploy_helm_feed/import.sh @@ -0,0 +1 @@ +terraform import [options] octopusdeploy_helm_feed. \ No newline at end of file diff --git a/examples/resources/octopusdeploy_helm_feed/resource.tf b/examples/resources/octopusdeploy_helm_feed/resource.tf new file mode 100644 index 000000000..854475848 --- /dev/null +++ b/examples/resources/octopusdeploy_helm_feed/resource.tf @@ -0,0 +1,6 @@ +resource "octopusdeploy_helm_feed" "example" { + feed_uri = "https://charts.helm.sh/stable" + password = "test-password" + name = "Test Helm Feed (OK to Delete)" + username = "test-username" +} diff --git a/examples/resources/octopusdeploy_nuget_feed/import.sh b/examples/resources/octopusdeploy_nuget_feed/import.sh new file mode 100644 index 000000000..e27df6a55 --- /dev/null +++ b/examples/resources/octopusdeploy_nuget_feed/import.sh @@ -0,0 +1 @@ +terraform import [options] octopusdeploy_nuget_feed. \ No newline at end of file diff --git a/examples/resources/octopusdeploy_nuget_feed/resource.tf b/examples/resources/octopusdeploy_nuget_feed/resource.tf new file mode 100644 index 000000000..4a3629e8c --- /dev/null +++ b/examples/resources/octopusdeploy_nuget_feed/resource.tf @@ -0,0 +1,9 @@ +resource "octopusdeploy_nuget_feed" "example" { + download_attempts = 1 + download_retry_backoff_seconds = 30 + feed_uri = "https://api.nuget.org/v3/index.json" + is_enhanced_mode = true + password = "test-password" + name = "Test NuGet Feed (OK to Delete)" + username = "test-username" +} diff --git a/octopusdeploy/provider.go b/octopusdeploy/provider.go index a1c5eb98e..034de72e6 100644 --- a/octopusdeploy/provider.go +++ b/octopusdeploy/provider.go @@ -44,6 +44,7 @@ func Provider() *schema.Provider { ResourcesMap: map[string]*schema.Resource{ "octopusdeploy_account": resourceAccount(), "octopusdeploy_aws_account": resourceAmazonWebServicesAccount(), + "octopusdeploy_aws_elastic_container_registry": resourceAwsElasticContainerRegistry(), "octopusdeploy_azure_cloud_service_deployment_target": resourceAzureCloudServiceDeploymentTarget(), "octopusdeploy_azure_service_fabric_cluster_deployment_target": resourceAzureServiceFabricClusterDeploymentTarget(), "octopusdeploy_azure_service_principal": resourceAzureServicePrincipalAccount(), @@ -54,13 +55,17 @@ func Provider() *schema.Provider { "octopusdeploy_cloud_region_deployment_target": resourceCloudRegionDeploymentTarget(), "octopusdeploy_deployment_process": resourceDeploymentProcess(), "octopusdeploy_deployment_target": resourceDeploymentTarget(), + "octopusdeploy_docker_container_registry": resourceDockerContainerRegistry(), "octopusdeploy_environment": resourceEnvironment(), "octopusdeploy_feed": resourceFeed(), + "octopusdeploy_github_repository_feed": resourceGitHubRepositoryFeed(), + "octopusdeploy_helm_feed": resourceHelmFeed(), "octopusdeploy_kubernetes_cluster_deployment_target": resourceKubernetesClusterDeploymentTarget(), "octopusdeploy_library_variable_set": resourceLibraryVariableSet(), "octopusdeploy_lifecycle": resourceLifecycle(), "octopusdeploy_listening_tentacle_deployment_target": resourceListeningTentacleDeploymentTarget(), "octopusdeploy_machine_policy": resourceMachinePolicy(), + "octopusdeploy_maven_feed": resourceMavenFeed(), "octopusdeploy_nuget_feed": resourceNuGetFeed(), "octopusdeploy_offline_package_drop_deployment_target": resourceOfflinePackageDropDeploymentTarget(), "octopusdeploy_polling_tentacle_deployment_target": resourcePollingTentacleDeploymentTarget(), diff --git a/octopusdeploy/resource_aws_elastic_container_registry.go b/octopusdeploy/resource_aws_elastic_container_registry.go new file mode 100644 index 000000000..5247db614 --- /dev/null +++ b/octopusdeploy/resource_aws_elastic_container_registry.go @@ -0,0 +1,111 @@ +package octopusdeploy + +import ( + "context" + "log" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceAwsElasticContainerRegistry() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceAwsElasticContainerRegistryCreate, + DeleteContext: resourceAwsElasticContainerRegistryDelete, + Description: "This resource manages a AWS Elastic Container Registry in Octopus Deploy.", + Importer: getImporter(), + ReadContext: resourceAwsElasticContainerRegistryRead, + Schema: getAwsElasticContainerRegistrySchema(), + UpdateContext: resourceAwsElasticContainerRegistryUpdate, + } +} + +func resourceAwsElasticContainerRegistryCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dockerContainerRegistry := expandAwsElasticContainerRegistry(d) + + log.Printf("[INFO] creating AWS Elastic Container Registry: %#v", dockerContainerRegistry) + + client := m.(*octopusdeploy.Client) + createdAwsElasticContainerRegistry, err := client.Feeds.Add(dockerContainerRegistry) + if err != nil { + return diag.FromErr(err) + } + + if err := setAwsElasticContainerRegistry(ctx, d, createdAwsElasticContainerRegistry.(*octopusdeploy.AwsElasticContainerRegistry)); err != nil { + return diag.FromErr(err) + } + + d.SetId(createdAwsElasticContainerRegistry.GetID()) + + log.Printf("[INFO] AWS Elastic Container Registry created (%s)", d.Id()) + return nil +} + +func resourceAwsElasticContainerRegistryDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] deleting AWS Elastic Container Registry (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + err := client.Feeds.DeleteByID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + log.Printf("[INFO] AWS Elastic Container Registry deleted") + return nil +} + +func resourceAwsElasticContainerRegistryRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] reading AWS Elastic Container Registry (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + feedResource, err := client.Feeds.GetByID(d.Id()) + if err != nil { + apiError := err.(*octopusdeploy.APIError) + if apiError.StatusCode == 404 { + log.Printf("[INFO] AWS Elastic Container Registry (%s) not found; deleting from state", d.Id()) + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + feedResource, err = octopusdeploy.ToFeed(feedResource.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + dockerContainerRegistry := feedResource.(*octopusdeploy.AwsElasticContainerRegistry) + if err := setAwsElasticContainerRegistry(ctx, d, dockerContainerRegistry); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] AWS Elastic Container Registry read: %#v", dockerContainerRegistry) + return nil +} + +func resourceAwsElasticContainerRegistryUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + feed := expandAwsElasticContainerRegistry(d) + + log.Printf("[INFO] updating AWS Elastic Container Registry: %#v", feed) + + client := m.(*octopusdeploy.Client) + updatedFeed, err := client.Feeds.Update(feed) + if err != nil { + return diag.FromErr(err) + } + + feedResource, err := octopusdeploy.ToFeed(updatedFeed.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + if err := setAwsElasticContainerRegistry(ctx, d, feedResource.(*octopusdeploy.AwsElasticContainerRegistry)); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] AWS Elastic Container Registry updated (%s)", d.Id()) + return nil +} diff --git a/octopusdeploy/resource_docker_container_registry.go b/octopusdeploy/resource_docker_container_registry.go new file mode 100644 index 000000000..c37521d7f --- /dev/null +++ b/octopusdeploy/resource_docker_container_registry.go @@ -0,0 +1,111 @@ +package octopusdeploy + +import ( + "context" + "log" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceDockerContainerRegistry() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceDockerContainerRegistryCreate, + DeleteContext: resourceDockerContainerRegistryDelete, + Description: "This resource manages a Docker Container Registry in Octopus Deploy.", + Importer: getImporter(), + ReadContext: resourceDockerContainerRegistryRead, + Schema: getDockerContainerRegistrySchema(), + UpdateContext: resourceDockerContainerRegistryUpdate, + } +} + +func resourceDockerContainerRegistryCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dockerContainerRegistry := expandDockerContainerRegistry(d) + + log.Printf("[INFO] creating Docker container registry: %#v", dockerContainerRegistry) + + client := m.(*octopusdeploy.Client) + createdDockerContainerRegistry, err := client.Feeds.Add(dockerContainerRegistry) + if err != nil { + return diag.FromErr(err) + } + + if err := setDockerContainerRegistry(ctx, d, createdDockerContainerRegistry.(*octopusdeploy.DockerContainerRegistry)); err != nil { + return diag.FromErr(err) + } + + d.SetId(createdDockerContainerRegistry.GetID()) + + log.Printf("[INFO] Docker container registry created (%s)", d.Id()) + return nil +} + +func resourceDockerContainerRegistryDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] deleting Docker container registry (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + err := client.Feeds.DeleteByID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + log.Printf("[INFO] Docker container registry deleted") + return nil +} + +func resourceDockerContainerRegistryRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] reading Docker container registry (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + feedResource, err := client.Feeds.GetByID(d.Id()) + if err != nil { + apiError := err.(*octopusdeploy.APIError) + if apiError.StatusCode == 404 { + log.Printf("[INFO] Docker container registry (%s) not found; deleting from state", d.Id()) + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + feedResource, err = octopusdeploy.ToFeed(feedResource.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + dockerContainerRegistry := feedResource.(*octopusdeploy.DockerContainerRegistry) + if err := setDockerContainerRegistry(ctx, d, dockerContainerRegistry); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] Docker container registry read: %#v", dockerContainerRegistry) + return nil +} + +func resourceDockerContainerRegistryUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + feed := expandDockerContainerRegistry(d) + + log.Printf("[INFO] updating Docker container registry: %#v", feed) + + client := m.(*octopusdeploy.Client) + updatedFeed, err := client.Feeds.Update(feed) + if err != nil { + return diag.FromErr(err) + } + + feedResource, err := octopusdeploy.ToFeed(updatedFeed.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + if err := setDockerContainerRegistry(ctx, d, feedResource.(*octopusdeploy.DockerContainerRegistry)); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] Docker container registry updated (%s)", d.Id()) + return nil +} diff --git a/octopusdeploy/resource_docker_container_registry_test.go b/octopusdeploy/resource_docker_container_registry_test.go new file mode 100644 index 000000000..9b2b548ae --- /dev/null +++ b/octopusdeploy/resource_docker_container_registry_test.go @@ -0,0 +1,82 @@ +package octopusdeploy + +import ( + "fmt" + "testing" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccOctopusDeployDockerContainerRegistry(t *testing.T) { + localName := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + prefix := "octopusdeploy_docker_container_registry." + localName + + apiVersion := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + feedURI := "https://index.docker.io" + name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + password := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + registryPath := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + username := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + + resource.Test(t, resource.TestCase{ + CheckDestroy: testDockerContainerRegistryCheckDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Check: resource.ComposeTestCheckFunc( + testDockerContainerRegistryExists(prefix), + resource.TestCheckResourceAttr(prefix, "api_version", apiVersion), + resource.TestCheckResourceAttr(prefix, "feed_uri", feedURI), + resource.TestCheckResourceAttr(prefix, "name", name), + resource.TestCheckResourceAttr(prefix, "password", password), + resource.TestCheckResourceAttr(prefix, "registry_path", registryPath), + resource.TestCheckResourceAttr(prefix, "username", username), + ), + Config: testDockerContainerRegistryBasic(localName, apiVersion, feedURI, name, registryPath, username, password), + }, + }, + }) +} + +func testDockerContainerRegistryBasic(localName string, apiVersion string, feedURI string, name string, registryPath string, username string, password string) string { + return fmt.Sprintf(`resource "octopusdeploy_docker_container_registry" "%s" { + api_version = "%s" + feed_uri = "%s" + name = "%s" + password = "%s" + registry_path = "%s" + username = "%s" + }`, localName, apiVersion, feedURI, name, password, registryPath, username) +} + +func testDockerContainerRegistryExists(prefix string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*octopusdeploy.Client) + feedID := s.RootModule().Resources[prefix].Primary.ID + if _, err := client.Feeds.GetByID(feedID); err != nil { + return err + } + + return nil + } +} + +func testDockerContainerRegistryCheckDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "octopusdeploy_docker_container_registry" { + continue + } + + client := testAccProvider.Meta().(*octopusdeploy.Client) + feed, err := client.Feeds.GetByID(rs.Primary.ID) + if err == nil && feed != nil { + return fmt.Errorf("Docker Container Registry (%s) still exists", rs.Primary.ID) + } + } + + return nil +} diff --git a/octopusdeploy/resource_github_repository_feed.go b/octopusdeploy/resource_github_repository_feed.go new file mode 100644 index 000000000..c70daae90 --- /dev/null +++ b/octopusdeploy/resource_github_repository_feed.go @@ -0,0 +1,111 @@ +package octopusdeploy + +import ( + "context" + "log" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceGitHubRepositoryFeed() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceGitHubRepositoryFeedCreate, + DeleteContext: resourceGitHubRepositoryFeedDelete, + Description: "This resource manages a GitHub repository feed in Octopus Deploy.", + Importer: getImporter(), + ReadContext: resourceGitHubRepositoryFeedRead, + Schema: getGitHubRepositoryFeedSchema(), + UpdateContext: resourceGitHubRepositoryFeedUpdate, + } +} + +func resourceGitHubRepositoryFeedCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dockerContainerRegistry := expandGitHubRepositoryFeed(d) + + log.Printf("[INFO] creating GitHub repository feed: %#v", dockerContainerRegistry) + + client := m.(*octopusdeploy.Client) + createdGitHubRepositoryFeed, err := client.Feeds.Add(dockerContainerRegistry) + if err != nil { + return diag.FromErr(err) + } + + if err := setGitHubRepositoryFeed(ctx, d, createdGitHubRepositoryFeed.(*octopusdeploy.GitHubRepositoryFeed)); err != nil { + return diag.FromErr(err) + } + + d.SetId(createdGitHubRepositoryFeed.GetID()) + + log.Printf("[INFO] GitHub repository feed created (%s)", d.Id()) + return nil +} + +func resourceGitHubRepositoryFeedDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] deleting GitHub repository feed (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + err := client.Feeds.DeleteByID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + log.Printf("[INFO] GitHub repository feed deleted") + return nil +} + +func resourceGitHubRepositoryFeedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] reading GitHub repository feed (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + feedResource, err := client.Feeds.GetByID(d.Id()) + if err != nil { + apiError := err.(*octopusdeploy.APIError) + if apiError.StatusCode == 404 { + log.Printf("[INFO] GitHub repository feed (%s) not found; deleting from state", d.Id()) + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + feedResource, err = octopusdeploy.ToFeed(feedResource.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + dockerContainerRegistry := feedResource.(*octopusdeploy.GitHubRepositoryFeed) + if err := setGitHubRepositoryFeed(ctx, d, dockerContainerRegistry); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] GitHub repository feed read: %#v", dockerContainerRegistry) + return nil +} + +func resourceGitHubRepositoryFeedUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + feed := expandGitHubRepositoryFeed(d) + + log.Printf("[INFO] updating GitHub repository feed: %#v", feed) + + client := m.(*octopusdeploy.Client) + updatedFeed, err := client.Feeds.Update(feed) + if err != nil { + return diag.FromErr(err) + } + + feedResource, err := octopusdeploy.ToFeed(updatedFeed.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + if err := setGitHubRepositoryFeed(ctx, d, feedResource.(*octopusdeploy.GitHubRepositoryFeed)); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] GitHub repository feed updated (%s)", d.Id()) + return nil +} diff --git a/octopusdeploy/resource_github_repository_feed_test.go b/octopusdeploy/resource_github_repository_feed_test.go new file mode 100644 index 000000000..ca895e6f2 --- /dev/null +++ b/octopusdeploy/resource_github_repository_feed_test.go @@ -0,0 +1,83 @@ +package octopusdeploy + +import ( + "fmt" + "strconv" + "testing" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestGitHubRepositoryFeed(t *testing.T) { + localName := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + prefix := "octopusdeploy_github_repository_feed." + localName + + downloadAttempts := acctest.RandIntRange(0, 10) + downloadRetryBackoffSeconds := acctest.RandIntRange(0, 60) + feedURI := "https://api.github.com" + name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + password := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + username := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + + resource.Test(t, resource.TestCase{ + CheckDestroy: testGitHubRepositoryFeedCheckDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Check: resource.ComposeTestCheckFunc( + testGitHubRepositoryFeedExists(prefix), + resource.TestCheckResourceAttr(prefix, "download_attempts", strconv.Itoa(downloadAttempts)), + resource.TestCheckResourceAttr(prefix, "download_retry_backoff_seconds", strconv.Itoa(downloadRetryBackoffSeconds)), + resource.TestCheckResourceAttr(prefix, "feed_uri", feedURI), + resource.TestCheckResourceAttr(prefix, "name", name), + resource.TestCheckResourceAttr(prefix, "password", password), + resource.TestCheckResourceAttr(prefix, "username", username), + ), + Config: testGitHubRepositoryFeedBasic(localName, downloadAttempts, downloadRetryBackoffSeconds, feedURI, name, username, password), + }, + }, + }) +} + +func testGitHubRepositoryFeedBasic(localName string, downloadAttempts int, downloadRetryBackoffSeconds int, feedURI string, name string, username string, password string) string { + return fmt.Sprintf(`resource "octopusdeploy_github_repository_feed" "%s" { + download_attempts = "%v" + download_retry_backoff_seconds = "%v" + feed_uri = "%s" + name = "%s" + password = "%s" + username = "%s" + }`, localName, downloadAttempts, downloadRetryBackoffSeconds, feedURI, name, password, username) +} + +func testGitHubRepositoryFeedExists(prefix string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*octopusdeploy.Client) + feedID := s.RootModule().Resources[prefix].Primary.ID + if _, err := client.Feeds.GetByID(feedID); err != nil { + return err + } + + return nil + } +} + +func testGitHubRepositoryFeedCheckDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "octopusdeploy_github_repository_feed" { + continue + } + + client := testAccProvider.Meta().(*octopusdeploy.Client) + feed, err := client.Feeds.GetByID(rs.Primary.ID) + if err == nil && feed != nil { + return fmt.Errorf("GitHub repository feed (%s) still exists", rs.Primary.ID) + } + } + + return nil +} diff --git a/octopusdeploy/resource_helm_feed.go b/octopusdeploy/resource_helm_feed.go new file mode 100644 index 000000000..6929b26c8 --- /dev/null +++ b/octopusdeploy/resource_helm_feed.go @@ -0,0 +1,111 @@ +package octopusdeploy + +import ( + "context" + "log" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceHelmFeed() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceHelmFeedCreate, + DeleteContext: resourceHelmFeedDelete, + Description: "This resource manages a Helm feed in Octopus Deploy.", + Importer: getImporter(), + ReadContext: resourceHelmFeedRead, + Schema: getHelmFeedSchema(), + UpdateContext: resourceHelmFeedUpdate, + } +} + +func resourceHelmFeedCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dockerContainerRegistry := expandHelmFeed(d) + + log.Printf("[INFO] creating Helm feed: %#v", dockerContainerRegistry) + + client := m.(*octopusdeploy.Client) + createdHelmFeed, err := client.Feeds.Add(dockerContainerRegistry) + if err != nil { + return diag.FromErr(err) + } + + if err := setHelmFeed(ctx, d, createdHelmFeed.(*octopusdeploy.HelmFeed)); err != nil { + return diag.FromErr(err) + } + + d.SetId(createdHelmFeed.GetID()) + + log.Printf("[INFO] Helm feed created (%s)", d.Id()) + return nil +} + +func resourceHelmFeedDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] deleting Helm feed (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + err := client.Feeds.DeleteByID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + log.Printf("[INFO] Helm feed deleted") + return nil +} + +func resourceHelmFeedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] reading Helm feed (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + feedResource, err := client.Feeds.GetByID(d.Id()) + if err != nil { + apiError := err.(*octopusdeploy.APIError) + if apiError.StatusCode == 404 { + log.Printf("[INFO] Helm feed (%s) not found; deleting from state", d.Id()) + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + feedResource, err = octopusdeploy.ToFeed(feedResource.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + dockerContainerRegistry := feedResource.(*octopusdeploy.HelmFeed) + if err := setHelmFeed(ctx, d, dockerContainerRegistry); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] Helm feed read: %#v", dockerContainerRegistry) + return nil +} + +func resourceHelmFeedUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + feed := expandHelmFeed(d) + + log.Printf("[INFO] updating Helm feed: %#v", feed) + + client := m.(*octopusdeploy.Client) + updatedFeed, err := client.Feeds.Update(feed) + if err != nil { + return diag.FromErr(err) + } + + feedResource, err := octopusdeploy.ToFeed(updatedFeed.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + if err := setHelmFeed(ctx, d, feedResource.(*octopusdeploy.HelmFeed)); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] Helm feed updated (%s)", d.Id()) + return nil +} diff --git a/octopusdeploy/resource_helm_feed_test.go b/octopusdeploy/resource_helm_feed_test.go new file mode 100644 index 000000000..5eb6ffc5e --- /dev/null +++ b/octopusdeploy/resource_helm_feed_test.go @@ -0,0 +1,76 @@ +package octopusdeploy + +import ( + "fmt" + "testing" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccOctopusDeployHelmFeed(t *testing.T) { + localName := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + prefix := "octopusdeploy_helm_feed." + localName + + feedURI := "https://charts.helm.sh/stable" + name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + password := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + username := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + + resource.Test(t, resource.TestCase{ + CheckDestroy: testHelmFeedCheckDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Check: resource.ComposeTestCheckFunc( + testHelmFeedExists(prefix), + resource.TestCheckResourceAttr(prefix, "feed_uri", feedURI), + resource.TestCheckResourceAttr(prefix, "name", name), + resource.TestCheckResourceAttr(prefix, "password", password), + resource.TestCheckResourceAttr(prefix, "username", username), + ), + Config: testHelmFeedBasic(localName, feedURI, name, username, password), + }, + }, + }) +} + +func testHelmFeedBasic(localName string, feedURI string, name string, username string, password string) string { + return fmt.Sprintf(`resource "octopusdeploy_helm_feed" "%s" { + feed_uri = "%s" + name = "%s" + password = "%s" + username = "%s" + }`, localName, feedURI, name, password, username) +} + +func testHelmFeedExists(prefix string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*octopusdeploy.Client) + feedID := s.RootModule().Resources[prefix].Primary.ID + if _, err := client.Feeds.GetByID(feedID); err != nil { + return err + } + + return nil + } +} + +func testHelmFeedCheckDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "octopusdeploy_helm_feed" { + continue + } + + client := testAccProvider.Meta().(*octopusdeploy.Client) + feed, err := client.Feeds.GetByID(rs.Primary.ID) + if err == nil && feed != nil { + return fmt.Errorf("Helm feed (%s) still exists", rs.Primary.ID) + } + } + + return nil +} diff --git a/octopusdeploy/resource_maven_feed.go b/octopusdeploy/resource_maven_feed.go new file mode 100644 index 000000000..4bd517df8 --- /dev/null +++ b/octopusdeploy/resource_maven_feed.go @@ -0,0 +1,111 @@ +package octopusdeploy + +import ( + "context" + "log" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceMavenFeed() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceMavenFeedCreate, + DeleteContext: resourceMavenFeedDelete, + Description: "This resource manages a Maven feed in Octopus Deploy.", + Importer: getImporter(), + ReadContext: resourceMavenFeedRead, + Schema: getMavenFeedSchema(), + UpdateContext: resourceMavenFeedUpdate, + } +} + +func resourceMavenFeedCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + dockerContainerRegistry := expandMavenFeed(d) + + log.Printf("[INFO] creating Maven feed: %#v", dockerContainerRegistry) + + client := m.(*octopusdeploy.Client) + createdMavenFeed, err := client.Feeds.Add(dockerContainerRegistry) + if err != nil { + return diag.FromErr(err) + } + + if err := setMavenFeed(ctx, d, createdMavenFeed.(*octopusdeploy.MavenFeed)); err != nil { + return diag.FromErr(err) + } + + d.SetId(createdMavenFeed.GetID()) + + log.Printf("[INFO] Maven feed created (%s)", d.Id()) + return nil +} + +func resourceMavenFeedDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] deleting Maven feed (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + err := client.Feeds.DeleteByID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("") + + log.Printf("[INFO] Maven feed deleted") + return nil +} + +func resourceMavenFeedRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + log.Printf("[INFO] reading Maven feed (%s)", d.Id()) + + client := m.(*octopusdeploy.Client) + feedResource, err := client.Feeds.GetByID(d.Id()) + if err != nil { + apiError := err.(*octopusdeploy.APIError) + if apiError.StatusCode == 404 { + log.Printf("[INFO] Maven feed (%s) not found; deleting from state", d.Id()) + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + feedResource, err = octopusdeploy.ToFeed(feedResource.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + dockerContainerRegistry := feedResource.(*octopusdeploy.MavenFeed) + if err := setMavenFeed(ctx, d, dockerContainerRegistry); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] Maven feed read: %#v", dockerContainerRegistry) + return nil +} + +func resourceMavenFeedUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + feed := expandMavenFeed(d) + + log.Printf("[INFO] updating Maven feed: %#v", feed) + + client := m.(*octopusdeploy.Client) + updatedFeed, err := client.Feeds.Update(feed) + if err != nil { + return diag.FromErr(err) + } + + feedResource, err := octopusdeploy.ToFeed(updatedFeed.(*octopusdeploy.FeedResource)) + if err != nil { + return diag.FromErr(err) + } + + if err := setMavenFeed(ctx, d, feedResource.(*octopusdeploy.MavenFeed)); err != nil { + return diag.FromErr(err) + } + + log.Printf("[INFO] Maven feed updated (%s)", d.Id()) + return nil +} diff --git a/octopusdeploy/resource_maven_feed_test.go b/octopusdeploy/resource_maven_feed_test.go new file mode 100644 index 000000000..48a254ca4 --- /dev/null +++ b/octopusdeploy/resource_maven_feed_test.go @@ -0,0 +1,83 @@ +package octopusdeploy + +import ( + "fmt" + "strconv" + "testing" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccOctopusDeployMavenFeed(t *testing.T) { + localName := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + prefix := "octopusdeploy_maven_feed." + localName + + downloadAttempts := acctest.RandIntRange(0, 10) + downloadRetryBackoffSeconds := acctest.RandIntRange(0, 60) + feedURI := "https://repo.maven.apache.org/maven2/" + name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + password := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + username := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + + resource.Test(t, resource.TestCase{ + CheckDestroy: testMavenFeedCheckDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Check: resource.ComposeTestCheckFunc( + testMavenFeedExists(prefix), + resource.TestCheckResourceAttr(prefix, "download_attempts", strconv.Itoa(downloadAttempts)), + resource.TestCheckResourceAttr(prefix, "download_retry_backoff_seconds", strconv.Itoa(downloadRetryBackoffSeconds)), + resource.TestCheckResourceAttr(prefix, "feed_uri", feedURI), + resource.TestCheckResourceAttr(prefix, "name", name), + resource.TestCheckResourceAttr(prefix, "password", password), + resource.TestCheckResourceAttr(prefix, "username", username), + ), + Config: testMavenFeedBasic(localName, downloadAttempts, downloadRetryBackoffSeconds, feedURI, name, username, password), + }, + }, + }) +} + +func testMavenFeedBasic(localName string, downloadAttempts int, downloadRetryBackoffSeconds int, feedURI string, name string, username string, password string) string { + return fmt.Sprintf(`resource "octopusdeploy_maven_feed" "%s" { + download_attempts = "%v" + download_retry_backoff_seconds = "%v" + feed_uri = "%s" + name = "%s" + password = "%s" + username = "%s" + }`, localName, downloadAttempts, downloadRetryBackoffSeconds, feedURI, name, password, username) +} + +func testMavenFeedExists(prefix string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*octopusdeploy.Client) + feedID := s.RootModule().Resources[prefix].Primary.ID + if _, err := client.Feeds.GetByID(feedID); err != nil { + return err + } + + return nil + } +} + +func testMavenFeedCheckDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "octopusdeploy_maven_feed" { + continue + } + + client := testAccProvider.Meta().(*octopusdeploy.Client) + feed, err := client.Feeds.GetByID(rs.Primary.ID) + if err == nil && feed != nil { + return fmt.Errorf("Maven feed (%s) still exists", rs.Primary.ID) + } + } + + return nil +} diff --git a/octopusdeploy/resource_nuget_feed.go b/octopusdeploy/resource_nuget_feed.go index b77d8476d..5a4bd9019 100644 --- a/octopusdeploy/resource_nuget_feed.go +++ b/octopusdeploy/resource_nuget_feed.go @@ -12,6 +12,7 @@ func resourceNuGetFeed() *schema.Resource { return &schema.Resource{ CreateContext: resourceNuGetFeedCreate, DeleteContext: resourceNuGetFeedDelete, + Description: "This resource manages a NuGet feed in Octopus Deploy.", Importer: getImporter(), ReadContext: resourceNuGetFeedRead, Schema: getNuGetFeedSchema(), diff --git a/octopusdeploy/resource_nuget_feed_test.go b/octopusdeploy/resource_nuget_feed_test.go index 0858d5ae8..2c2fc0fd5 100644 --- a/octopusdeploy/resource_nuget_feed_test.go +++ b/octopusdeploy/resource_nuget_feed_test.go @@ -6,17 +6,20 @@ import ( "testing" "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func TestAccOctopusDeployNuGetFeedBasic(t *testing.T) { - const feedPrefix = "octopusdeploy_nuget_feed.foo" - const feedName = "Testing Nuget one two three" - const feedURI = "http://test.com" - const enhancedMode = true - const feedUsername = "username" - const feedPassword = "password" + localName := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + prefix := "octopusdeploy_nuget_feed." + localName + + name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + feedURI := "http://test.com" + isEnhancedMode := true + username := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) + password := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -24,34 +27,34 @@ func TestAccOctopusDeployNuGetFeedBasic(t *testing.T) { CheckDestroy: testOctopusDeployNuGetFeedDestroy, Steps: []resource.TestStep{ { - Config: testNuGetFeedBasic(feedName, feedURI, feedUsername, feedPassword, enhancedMode), + Config: testNuGetFeedBasic(localName, name, feedURI, username, password, isEnhancedMode), Check: resource.ComposeTestCheckFunc( - testOctopusDeployNuGetFeedExists(feedPrefix), - resource.TestCheckResourceAttr(feedPrefix, "name", feedName), - resource.TestCheckResourceAttr(feedPrefix, "feed_uri", feedURI), - resource.TestCheckResourceAttr(feedPrefix, "username", feedUsername), - resource.TestCheckResourceAttr(feedPrefix, "password", feedPassword), - resource.TestCheckResourceAttr(feedPrefix, "is_enhanced_mode", strconv.FormatBool(enhancedMode)), + testOctopusDeployNuGetFeedExists(prefix), + resource.TestCheckResourceAttr(prefix, "feed_uri", feedURI), + resource.TestCheckResourceAttr(prefix, "is_enhanced_mode", strconv.FormatBool(isEnhancedMode)), + resource.TestCheckResourceAttr(prefix, "name", name), + resource.TestCheckResourceAttr(prefix, "password", password), + resource.TestCheckResourceAttr(prefix, "username", username), ), }, }, }) } -func testNuGetFeedBasic(name, feedURI string, username string, password string, isEnhancedMode bool) string { - return fmt.Sprintf(`resource "octopusdeploy_nuget_feed" "foo" { +func testNuGetFeedBasic(localName string, name string, feedURI string, username string, password string, isEnhancedMode bool) string { + return fmt.Sprintf(`resource "octopusdeploy_nuget_feed" "%s" { feed_uri = "%s" is_enhanced_mode = %v name = "%s" password = "%s" username = "%s" - }`, feedURI, isEnhancedMode, name, password, username) + }`, localName, feedURI, isEnhancedMode, name, password, username) } -func testOctopusDeployNuGetFeedExists(n string) resource.TestCheckFunc { +func testOctopusDeployNuGetFeedExists(prefix string) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*octopusdeploy.Client) - feedID := s.RootModule().Resources[n].Primary.ID + feedID := s.RootModule().Resources[prefix].Primary.ID if _, err := client.Feeds.GetByID(feedID); err != nil { return err } diff --git a/octopusdeploy/schema_aws_elastic_container_registry.go b/octopusdeploy/schema_aws_elastic_container_registry.go new file mode 100644 index 000000000..af5bd407b --- /dev/null +++ b/octopusdeploy/schema_aws_elastic_container_registry.go @@ -0,0 +1,90 @@ +package octopusdeploy + +import ( + "context" + "fmt" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func expandAwsElasticContainerRegistry(d *schema.ResourceData) *octopusdeploy.AwsElasticContainerRegistry { + accessKey := d.Get("access_key").(string) + name := d.Get("name").(string) + secretKey := octopusdeploy.NewSensitiveValue(d.Get("secret_key").(string)) + region := d.Get("region").(string) + + var awsElasticContainerRegistry = octopusdeploy.NewAwsElasticContainerRegistry(name, accessKey, secretKey, region) + awsElasticContainerRegistry.ID = d.Id() + + if v, ok := d.GetOk("package_acquisition_location_options"); ok { + awsElasticContainerRegistry.PackageAcquisitionLocationOptions = getSliceFromTerraformTypeList(v) + } + + if v, ok := d.GetOk("space_id"); ok { + awsElasticContainerRegistry.SpaceID = v.(string) + } + + return awsElasticContainerRegistry +} + +func getAwsElasticContainerRegistrySchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "access_key": { + Description: "The AWS access key to use when authenticating against Amazon Web Services.", + Required: true, + Type: schema.TypeString, + }, + "id": { + Computed: true, + Description: "The unique ID for this feed.", + Optional: true, + Type: schema.TypeString, + }, + "name": { + Description: "A short, memorable, unique name for this feed. Example: ACME Builds.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty), + }, + "package_acquisition_location_options": { + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Type: schema.TypeList, + }, + "region": { + Description: "The AWS region where the registry resides.", + Required: true, + Type: schema.TypeString, + }, + "secret_key": { + Description: "The AWS secret key to use when authenticating against Amazon Web Services.", + Required: true, + Sensitive: true, + Type: schema.TypeString, + }, + "space_id": { + Computed: true, + Description: "The space ID associated with this feed.", + Optional: true, + Type: schema.TypeString, + }, + } +} + +func setAwsElasticContainerRegistry(ctx context.Context, d *schema.ResourceData, awsElasticContainerRegistry *octopusdeploy.AwsElasticContainerRegistry) error { + d.Set("access_key", awsElasticContainerRegistry.AccessKey) + d.Set("name", awsElasticContainerRegistry.Name) + d.Set("space_id", awsElasticContainerRegistry.SpaceID) + d.Set("region", awsElasticContainerRegistry.Region) + + if err := d.Set("package_acquisition_location_options", awsElasticContainerRegistry.PackageAcquisitionLocationOptions); err != nil { + return fmt.Errorf("error setting package_acquisition_location_options: %s", err) + } + + d.SetId(awsElasticContainerRegistry.GetID()) + + return nil +} diff --git a/octopusdeploy/schema_docker_container_registry.go b/octopusdeploy/schema_docker_container_registry.go new file mode 100644 index 000000000..2775ea1bf --- /dev/null +++ b/octopusdeploy/schema_docker_container_registry.go @@ -0,0 +1,99 @@ +package octopusdeploy + +import ( + "context" + "fmt" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func expandDockerContainerRegistry(d *schema.ResourceData) *octopusdeploy.DockerContainerRegistry { + name := d.Get("name").(string) + + var dockerContainerRegistry = octopusdeploy.NewDockerContainerRegistry(name) + dockerContainerRegistry.ID = d.Id() + + if v, ok := d.GetOk("api_version"); ok { + dockerContainerRegistry.APIVersion = v.(string) + } + + if v, ok := d.GetOk("feed_uri"); ok { + dockerContainerRegistry.FeedURI = v.(string) + } + + if v, ok := d.GetOk("registry_path"); ok { + dockerContainerRegistry.RegistryPath = v.(string) + } + + if v, ok := d.GetOk("space_id"); ok { + dockerContainerRegistry.SpaceID = v.(string) + } + + if v, ok := d.GetOk("package_acquisition_location_options"); ok { + dockerContainerRegistry.PackageAcquisitionLocationOptions = getSliceFromTerraformTypeList(v) + } + + if v, ok := d.GetOk("password"); ok { + dockerContainerRegistry.Password = octopusdeploy.NewSensitiveValue(v.(string)) + } + + if v, ok := d.GetOk("username"); ok { + dockerContainerRegistry.Username = v.(string) + } + + return dockerContainerRegistry +} + +func getDockerContainerRegistrySchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "api_version": { + Optional: true, + Type: schema.TypeString, + }, + "feed_uri": { + Description: "The URL to a Maven repository. This URL is the same value defined in the `repositories`/`repository`/`url` element of a Maven `settings.xml` file.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.IsURLWithHTTPorHTTPS), + }, + "id": getIDSchema(), + "name": { + Description: "A short, memorable, unique name for this feed. Example: ACME Builds.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty), + }, + "password": getPasswordSchema(false), + "package_acquisition_location_options": { + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Type: schema.TypeList, + }, + "registry_path": { + Optional: true, + Type: schema.TypeString, + }, + "space_id": getSpaceIDSchema(), + "username": getUsernameSchema(false), + } +} + +func setDockerContainerRegistry(ctx context.Context, d *schema.ResourceData, dockerContainerRegistry *octopusdeploy.DockerContainerRegistry) error { + d.Set("api_version", dockerContainerRegistry.APIVersion) + d.Set("feed_uri", dockerContainerRegistry.FeedURI) + d.Set("name", dockerContainerRegistry.Name) + d.Set("registry_path", dockerContainerRegistry.RegistryPath) + d.Set("space_id", dockerContainerRegistry.SpaceID) + d.Set("username", dockerContainerRegistry.Username) + + if err := d.Set("package_acquisition_location_options", dockerContainerRegistry.PackageAcquisitionLocationOptions); err != nil { + return fmt.Errorf("error setting package_acquisition_location_options: %s", err) + } + + d.SetId(dockerContainerRegistry.GetID()) + + return nil +} diff --git a/octopusdeploy/schema_feed.go b/octopusdeploy/schema_feed.go index 515441fab..8498aef24 100644 --- a/octopusdeploy/schema_feed.go +++ b/octopusdeploy/schema_feed.go @@ -6,6 +6,7 @@ import ( "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) func expandFeed(d *schema.ResourceData) *octopusdeploy.FeedResource { @@ -101,14 +102,16 @@ func getFeedSchema() map[string]*schema.Schema { Type: schema.TypeInt, }, "download_attempts": { - Default: 5, - Optional: true, - Type: schema.TypeInt, + Default: 5, + Description: "The number of times a deployment should attempt to download a package from this feed before failing.", + Optional: true, + Type: schema.TypeInt, }, "download_retry_backoff_seconds": { - Default: 10, - Optional: true, - Type: schema.TypeInt, + Default: 10, + Description: "The number of seconds to apply as a linear back off between download attempts.", + Optional: true, + Type: schema.TypeInt, }, "feed_type": { Default: "None", @@ -136,7 +139,12 @@ func getFeedSchema() map[string]*schema.Schema { Optional: true, Type: schema.TypeBool, }, - "name": getNameSchema(true), + "name": { + Description: "A short, memorable, unique name for this feed. Example: ACME Builds.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty), + }, "password": getPasswordSchema(false), "package_acquisition_location_options": { Computed: true, diff --git a/octopusdeploy/schema_github_repository_feed.go b/octopusdeploy/schema_github_repository_feed.go new file mode 100644 index 000000000..56f0d0727 --- /dev/null +++ b/octopusdeploy/schema_github_repository_feed.go @@ -0,0 +1,97 @@ +package octopusdeploy + +import ( + "context" + "fmt" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func expandGitHubRepositoryFeed(d *schema.ResourceData) *octopusdeploy.GitHubRepositoryFeed { + name := d.Get("name").(string) + + var gitHubRepositoryFeed = octopusdeploy.NewGitHubRepositoryFeed(name) + gitHubRepositoryFeed.ID = d.Id() + + if v, ok := d.GetOk("download_attempts"); ok { + gitHubRepositoryFeed.DownloadAttempts = v.(int) + } + + if v, ok := d.GetOk("download_retry_backoff_seconds"); ok { + gitHubRepositoryFeed.DownloadRetryBackoffSeconds = v.(int) + } + + if v, ok := d.GetOk("feed_uri"); ok { + gitHubRepositoryFeed.FeedURI = v.(string) + } + + if v, ok := d.GetOk("package_acquisition_location_options"); ok { + gitHubRepositoryFeed.PackageAcquisitionLocationOptions = getSliceFromTerraformTypeList(v) + } + + if v, ok := d.GetOk("password"); ok { + gitHubRepositoryFeed.Password = octopusdeploy.NewSensitiveValue(v.(string)) + } + + if v, ok := d.GetOk("username"); ok { + gitHubRepositoryFeed.Username = v.(string) + } + + return gitHubRepositoryFeed +} + +func getGitHubRepositoryFeedSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "download_attempts": { + Default: 5, + Description: "The number of times a deployment should attempt to download a package from this feed before failing.", + Optional: true, + Type: schema.TypeInt, + }, + "download_retry_backoff_seconds": { + Default: 10, + Description: "The number of seconds to apply as a linear back off between download attempts.", + Optional: true, + Type: schema.TypeInt, + }, + "feed_uri": { + Required: true, + Type: schema.TypeString, + }, + "id": getIDSchema(), + "name": { + Description: "A short, memorable, unique name for this feed. Example: ACME Builds.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty), + }, + "package_acquisition_location_options": { + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Type: schema.TypeList, + }, + "password": getPasswordSchema(false), + "space_id": getSpaceIDSchema(), + "username": getUsernameSchema(false), + } +} + +func setGitHubRepositoryFeed(ctx context.Context, d *schema.ResourceData, githubRepositoryFeed *octopusdeploy.GitHubRepositoryFeed) error { + d.Set("download_attempts", githubRepositoryFeed.DownloadAttempts) + d.Set("download_retry_backoff_seconds", githubRepositoryFeed.DownloadRetryBackoffSeconds) + d.Set("feed_uri", githubRepositoryFeed.FeedURI) + d.Set("name", githubRepositoryFeed.Name) + d.Set("space_id", githubRepositoryFeed.SpaceID) + d.Set("username", githubRepositoryFeed.Username) + + if err := d.Set("package_acquisition_location_options", githubRepositoryFeed.PackageAcquisitionLocationOptions); err != nil { + return fmt.Errorf("error setting package_acquisition_location_options: %s", err) + } + + d.SetId(githubRepositoryFeed.GetID()) + + return nil +} diff --git a/octopusdeploy/schema_helm_feed.go b/octopusdeploy/schema_helm_feed.go new file mode 100644 index 000000000..7433cb56e --- /dev/null +++ b/octopusdeploy/schema_helm_feed.go @@ -0,0 +1,75 @@ +package octopusdeploy + +import ( + "context" + "fmt" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func expandHelmFeed(d *schema.ResourceData) *octopusdeploy.HelmFeed { + name := d.Get("name").(string) + + var helmFeed = octopusdeploy.NewHelmFeed(name) + helmFeed.ID = d.Id() + + if v, ok := d.GetOk("feed_uri"); ok { + helmFeed.FeedURI = v.(string) + } + + if v, ok := d.GetOk("package_acquisition_location_options"); ok { + helmFeed.PackageAcquisitionLocationOptions = getSliceFromTerraformTypeList(v) + } + + if v, ok := d.GetOk("password"); ok { + helmFeed.Password = octopusdeploy.NewSensitiveValue(v.(string)) + } + + if v, ok := d.GetOk("username"); ok { + helmFeed.Username = v.(string) + } + + return helmFeed +} + +func getHelmFeedSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "feed_uri": { + Required: true, + Type: schema.TypeString, + }, + "id": getIDSchema(), + "name": { + Description: "A short, memorable, unique name for this feed. Example: ACME Builds.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty), + }, + "package_acquisition_location_options": { + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Type: schema.TypeList, + }, + "password": getPasswordSchema(false), + "space_id": getSpaceIDSchema(), + "username": getUsernameSchema(false), + } +} + +func setHelmFeed(ctx context.Context, d *schema.ResourceData, mavenFeed *octopusdeploy.HelmFeed) error { + d.Set("feed_uri", mavenFeed.FeedURI) + d.Set("name", mavenFeed.Name) + d.Set("space_id", mavenFeed.SpaceID) + d.Set("username", mavenFeed.Username) + + if err := d.Set("package_acquisition_location_options", mavenFeed.PackageAcquisitionLocationOptions); err != nil { + return fmt.Errorf("error setting package_acquisition_location_options: %s", err) + } + + d.SetId(mavenFeed.GetID()) + + return nil +} diff --git a/octopusdeploy/schema_maven_feed.go b/octopusdeploy/schema_maven_feed.go new file mode 100644 index 000000000..e8efd44d9 --- /dev/null +++ b/octopusdeploy/schema_maven_feed.go @@ -0,0 +1,97 @@ +package octopusdeploy + +import ( + "context" + "fmt" + + "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func expandMavenFeed(d *schema.ResourceData) *octopusdeploy.MavenFeed { + name := d.Get("name").(string) + + var mavenFeed = octopusdeploy.NewMavenFeed(name) + mavenFeed.ID = d.Id() + + if v, ok := d.GetOk("download_attempts"); ok { + mavenFeed.DownloadAttempts = v.(int) + } + + if v, ok := d.GetOk("download_retry_backoff_seconds"); ok { + mavenFeed.DownloadRetryBackoffSeconds = v.(int) + } + + if v, ok := d.GetOk("feed_uri"); ok { + mavenFeed.FeedURI = v.(string) + } + + if v, ok := d.GetOk("package_acquisition_location_options"); ok { + mavenFeed.PackageAcquisitionLocationOptions = getSliceFromTerraformTypeList(v) + } + + if v, ok := d.GetOk("password"); ok { + mavenFeed.Password = octopusdeploy.NewSensitiveValue(v.(string)) + } + + if v, ok := d.GetOk("username"); ok { + mavenFeed.Username = v.(string) + } + + return mavenFeed +} + +func getMavenFeedSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "download_attempts": { + Default: 5, + Description: "The number of times a deployment should attempt to download a package from this feed before failing.", + Optional: true, + Type: schema.TypeInt, + }, + "download_retry_backoff_seconds": { + Default: 10, + Description: "The number of seconds to apply as a linear back off between download attempts.", + Optional: true, + Type: schema.TypeInt, + }, + "feed_uri": { + Required: true, + Type: schema.TypeString, + }, + "id": getIDSchema(), + "name": { + Description: "A short, memorable, unique name for this feed. Example: ACME Builds.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty), + }, + "package_acquisition_location_options": { + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Type: schema.TypeList, + }, + "password": getPasswordSchema(false), + "space_id": getSpaceIDSchema(), + "username": getUsernameSchema(false), + } +} + +func setMavenFeed(ctx context.Context, d *schema.ResourceData, mavenFeed *octopusdeploy.MavenFeed) error { + d.Set("download_attempts", mavenFeed.DownloadAttempts) + d.Set("download_retry_backoff_seconds", mavenFeed.DownloadRetryBackoffSeconds) + d.Set("feed_uri", mavenFeed.FeedURI) + d.Set("name", mavenFeed.Name) + d.Set("space_id", mavenFeed.SpaceID) + d.Set("username", mavenFeed.Username) + + if err := d.Set("package_acquisition_location_options", mavenFeed.PackageAcquisitionLocationOptions); err != nil { + return fmt.Errorf("error setting package_acquisition_location_options: %s", err) + } + + d.SetId(mavenFeed.GetID()) + + return nil +} diff --git a/octopusdeploy/schema_nuget_feed.go b/octopusdeploy/schema_nuget_feed.go index 3c77d28f2..d4dad9c2c 100644 --- a/octopusdeploy/schema_nuget_feed.go +++ b/octopusdeploy/schema_nuget_feed.go @@ -2,83 +2,104 @@ package octopusdeploy import ( "context" + "fmt" "github.com/OctopusDeploy/go-octopusdeploy/octopusdeploy" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) func expandNuGetFeed(d *schema.ResourceData) *octopusdeploy.NuGetFeed { name := d.Get("name").(string) feedURI := d.Get("feed_uri").(string) - feed := octopusdeploy.NewNuGetFeed(name, feedURI) - feed.ID = d.Id() + nuGetFeed := octopusdeploy.NewNuGetFeed(name, feedURI) + nuGetFeed.ID = d.Id() if v, ok := d.GetOk("download_attempts"); ok { - feed.DownloadAttempts = v.(int) + nuGetFeed.DownloadAttempts = v.(int) } if v, ok := d.GetOk("download_retry_backoff_seconds"); ok { - feed.DownloadRetryBackoffSeconds = v.(int) + nuGetFeed.DownloadRetryBackoffSeconds = v.(int) } if v, ok := d.GetOk("is_enhanced_mode"); ok { - feed.EnhancedMode = v.(bool) + nuGetFeed.EnhancedMode = v.(bool) } - if v, ok := d.GetOk("username"); ok { - feed.Username = v.(string) + if v, ok := d.GetOk("package_acquisition_location_options"); ok { + nuGetFeed.PackageAcquisitionLocationOptions = getSliceFromTerraformTypeList(v) } if v, ok := d.GetOk("password"); ok { - feed.Password = octopusdeploy.NewSensitiveValue(v.(string)) + nuGetFeed.Password = octopusdeploy.NewSensitiveValue(v.(string)) } - return feed -} - -func getNuGetFeedDataSchema() map[string]*schema.Schema { - return map[string]*schema.Schema{ - "name": getNameSchema(true), + if v, ok := d.GetOk("username"); ok { + nuGetFeed.Username = v.(string) } + + return nuGetFeed } func getNuGetFeedSchema() map[string]*schema.Schema { return map[string]*schema.Schema{ "download_attempts": { - Default: 5, - Optional: true, - Type: schema.TypeInt, + Default: 5, + Description: "The number of times a deployment should attempt to download a package from this feed before failing.", + Optional: true, + Type: schema.TypeInt, }, "download_retry_backoff_seconds": { - Default: 10, - Optional: true, - Type: schema.TypeInt, + Default: 10, + Description: "The number of seconds to apply as a linear back off between download attempts.", + Optional: true, + Type: schema.TypeInt, }, + "feed_uri": { + Description: "The feed URI can be a URL or a folder path.", + Required: true, + Type: schema.TypeString, + }, + "id": getIDSchema(), "is_enhanced_mode": { - Default: true, - Optional: true, - Type: schema.TypeBool, + Default: true, + Description: "This will improve performance of the NuGet feed but may not be supported by some older feeds. Disable if the operation, Create Release does not return the latest version for a package.", + Optional: true, + Type: schema.TypeBool, }, - "feed_uri": { - Required: true, - Type: schema.TypeString, + "name": { + Description: "A short, memorable, unique name for this feed. Example: ACME Builds.", + Required: true, + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringIsNotEmpty), + }, + "package_acquisition_location_options": { + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Type: schema.TypeList, }, - "name": getNameSchema(true), "password": getPasswordSchema(false), + "space_id": getSpaceIDSchema(), "username": getUsernameSchema(false), } } -func setNuGetFeed(ctx context.Context, d *schema.ResourceData, feed *octopusdeploy.NuGetFeed) error { - d.Set("download_attempts", feed.DownloadAttempts) - d.Set("download_retry_backoff_seconds", feed.DownloadRetryBackoffSeconds) - d.Set("feed_uri", feed.FeedURI) - d.Set("is_enhanced_mode", feed.EnhancedMode) - d.Set("name", feed.Name) - d.Set("username", feed.Username) +func setNuGetFeed(ctx context.Context, d *schema.ResourceData, nuGetFeed *octopusdeploy.NuGetFeed) error { + d.Set("download_attempts", nuGetFeed.DownloadAttempts) + d.Set("download_retry_backoff_seconds", nuGetFeed.DownloadRetryBackoffSeconds) + d.Set("feed_uri", nuGetFeed.FeedURI) + d.Set("is_enhanced_mode", nuGetFeed.EnhancedMode) + d.Set("name", nuGetFeed.Name) + d.Set("username", nuGetFeed.Username) + + if err := d.Set("package_acquisition_location_options", nuGetFeed.PackageAcquisitionLocationOptions); err != nil { + return fmt.Errorf("error setting package_acquisition_location_options: %s", err) + } - d.SetId(feed.GetID()) + d.SetId(nuGetFeed.GetID()) return nil } diff --git a/templates/resources/aws_elastic_container_registry.md.tmpl b/templates/resources/aws_elastic_container_registry.md.tmpl new file mode 100644 index 000000000..cd9bf748f --- /dev/null +++ b/templates/resources/aws_elastic_container_registry.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Feeds" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Type "/resource.tf") }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Type "/import.sh") }} \ No newline at end of file diff --git a/templates/resources/docker_container_registry.md.tmpl b/templates/resources/docker_container_registry.md.tmpl new file mode 100644 index 000000000..cd9bf748f --- /dev/null +++ b/templates/resources/docker_container_registry.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Feeds" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Type "/resource.tf") }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Type "/import.sh") }} \ No newline at end of file diff --git a/templates/resources/feed.md.tmpl b/templates/resources/feed.md.tmpl new file mode 100644 index 000000000..cd9bf748f --- /dev/null +++ b/templates/resources/feed.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Feeds" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Type "/resource.tf") }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Type "/import.sh") }} \ No newline at end of file diff --git a/templates/resources/github_repository_feed.md.tmpl b/templates/resources/github_repository_feed.md.tmpl new file mode 100644 index 000000000..cd9bf748f --- /dev/null +++ b/templates/resources/github_repository_feed.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Feeds" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Type "/resource.tf") }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Type "/import.sh") }} \ No newline at end of file diff --git a/templates/resources/helm_feed.md.tmpl b/templates/resources/helm_feed.md.tmpl new file mode 100644 index 000000000..cd9bf748f --- /dev/null +++ b/templates/resources/helm_feed.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Feeds" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Type "/resource.tf") }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Type "/import.sh") }} \ No newline at end of file diff --git a/templates/resources/maven_feed.md.tmpl b/templates/resources/maven_feed.md.tmpl new file mode 100644 index 000000000..cd9bf748f --- /dev/null +++ b/templates/resources/maven_feed.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Feeds" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Type "/resource.tf") }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Type "/import.sh") }} \ No newline at end of file diff --git a/templates/resources/nuget_feed.md.tmpl b/templates/resources/nuget_feed.md.tmpl new file mode 100644 index 000000000..cd9bf748f --- /dev/null +++ b/templates/resources/nuget_feed.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Feeds" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Type "/resource.tf") }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Type "/import.sh") }} \ No newline at end of file