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

fix: Handle use of provide config from environment variables #29

Merged
merged 1 commit into from
May 28, 2024
Merged
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
15 changes: 10 additions & 5 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ generate the username/tokens for a user can be found [here](https://help.sonatyp
# limitations under the License.
#

# Example of how to use the Sonatype IQ Terraform provider.
#
# *Warning*: The config attributes will override the environment variables (See Schema)

provider "sonatypeiq" {
host = "my-sonatype-iq-server.tld:port"
url = "my-sonatype-iq-server.tld:port"
username = "username"
password = "password"
}
Expand All @@ -36,8 +40,9 @@ provider "sonatypeiq" {
<!-- schema generated by tfplugindocs -->
## Schema

### Required
### Optional

- `password` (String, Sensitive) Password for your user for Sonatype IQ Server, if not provided will attempt to fall back to environment variable `IQ_SERVER_PASSWORD`
- `url` (String) Sonatype IQ Server URL, must start `http://` or `https://`, if not provided will attempt to fall back to environment variable `IQ_SERVER_URL`
- `username` (String) Username for Sonatype IQ Server, requires role/permissions scoped to the resources you wish to manage, if not provided will attempt to fall back to environment variable `IQ_SERVER_USERNAME`

- `password` (String, Sensitive) Password for your Administrator user for Sonatype IQ Server
- `url` (String) Sonatype IQ Server URL
- `username` (String) Administrator Username for Sonatype IQ Server
6 changes: 5 additions & 1 deletion examples/provider/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
# limitations under the License.
#

# Example of how to use the Sonatype IQ Terraform provider.
#
# *Warning*: The config attributes will override the environment variables (See Schema)

provider "sonatypeiq" {
host = "my-sonatype-iq-server.tld:port"
url = "my-sonatype-iq-server.tld:port"
username = "username"
password = "password"
}
39 changes: 26 additions & 13 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package provider

import (
"context"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"net/url"
"os"

Expand Down Expand Up @@ -58,17 +60,20 @@ func (p *SonatypeIqProvider) Schema(ctx context.Context, req provider.SchemaRequ
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"url": schema.StringAttribute{
MarkdownDescription: "Sonatype IQ Server URL",
Required: true,
MarkdownDescription: "Sonatype IQ Server URL, must start `http://` or `https://`, if not provided will attempt to fall back to environment variable `IQ_SERVER_URL`",
Optional: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(8)},
},
"username": schema.StringAttribute{
MarkdownDescription: "Username for Sonatype IQ Server, requires role/permissions scoped to the resources you wish to manage",
Required: true,
MarkdownDescription: "Username for Sonatype IQ Server, requires role/permissions scoped to the resources you wish to manage, if not provided will attempt to fall back to environment variable `IQ_SERVER_USERNAME`",
Optional: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1)},
},
"password": schema.StringAttribute{
MarkdownDescription: "Password for your user for Sonatype IQ Server",
Required: true,
MarkdownDescription: "Password for your user for Sonatype IQ Server, if not provided will attempt to fall back to environment variable `IQ_SERVER_PASSWORD`",
Optional: true,
Sensitive: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1)},
},
},
}
Expand All @@ -89,8 +94,16 @@ func (p *SonatypeIqProvider) Configure(ctx context.Context, req provider.Configu
username := os.Getenv("IQ_SERVER_USERNAME")
password := os.Getenv("IQ_SERVER_PASSWORD")

if !config.Url.IsNull() && len(config.Url.ValueString()) > 0 {
print("setting URL")
if !config.Url.IsNull() && len(iqUrl) > 0 {
resp.Diagnostics.AddWarning("Provider config override", "The provider config is overriding the environment variable `IQ_SERVER_URL`")
}
if !config.Username.IsNull() && len(username) > 0 {
resp.Diagnostics.AddWarning("Provider config override", "The provider config is overriding the environment variable `IQ_SERVER_USERNAME`")
}
if !config.Password.IsNull() && len(password) > 0 {
resp.Diagnostics.AddWarning("Provider config override", "The provider config is overriding the environment variable `IQ_SERVER_PASSWORD`")
}
if !config.Url.IsNull() {
iqUrl = config.Url.ValueString()
}

Expand Down Expand Up @@ -119,19 +132,19 @@ func (p *SonatypeIqProvider) Configure(ctx context.Context, req provider.Configu
)
}

if config.Username.IsUnknown() {
if len(username) == 0 {
resp.Diagnostics.AddAttributeError(
path.Root("username"),
"Username not supplied",
"Administratrive credentials for your Sonatype IQ Server are required",
"Administrative credentials for your Sonatype IQ Server are required",
)
}

if config.Password.IsUnknown() {
if len(password) == 0 {
resp.Diagnostics.AddAttributeError(
path.Root("password"),
"Username not supplied",
"Administratrive credentials for your Sonatype IQ Server are required",
"password not supplied",
"Administrative credentials for your Sonatype IQ Server are required",
)
}

Expand Down
53 changes: 43 additions & 10 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ package provider
import (
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"os"
"regexp"
"testing"
)

const (
// providerConfig is a shared configuration to combine with the actual
// test configuration.
providerConfig = `
provider "sonatypeiq" {
username = ""
password = ""
url = ""
}
provider "sonatypeiq" {}
`
)

Expand All @@ -41,8 +41,41 @@ var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServe
"sonatypeiq": providerserver.NewProtocol6WithError(New("test")()),
}

// func testAccPreCheck(t *testing.T) {
// // You can add code here to run prior to any test case execution, for example assertions
// // about the appropriate environment variables being set are common to see in a pre-check
// // function.
// }
// func testAccPreCheck(t *testing.T) {
// // You can add code here to run prior to any test case execution, for example assertions
// // about the appropriate environment variables being set are common to see in a pre-check
// // function.
// }

func TestAccProviderNoConfigurationEnvVarsEmpty(t *testing.T) {
originalUsername, usernameSet := os.LookupEnv("IQ_SERVER_USERNAME")
os.Unsetenv("IQ_SERVER_USERNAME")
originalPassword, PasswordSet := os.LookupEnv("IQ_SERVER_PASSWORD")
os.Unsetenv("IQ_SERVER_PASSWORD")
originalServerURL, serverURLSet := os.LookupEnv("IQ_SERVER_URL")
os.Unsetenv("IQ_SERVER_URL")
defer func() {
if usernameSet {
os.Setenv("IQ_SERVER_USERNAME", originalUsername)
}
if PasswordSet {
os.Setenv("IQ_SERVER_PASSWORD", originalPassword)
}
if serverURLSet {
os.Setenv("IQ_SERVER_URL", originalServerURL)
}
}()
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: providerConfig + `resource "sonatypeiq_application" "test" {
name = "test"
public_id = "test"
organization_id = "aaaaa"
}`,
ExpectError: regexp.MustCompile("(?s).*Unknown Sonatype IQ Server URL.*Invalid Sonatype IQ Server URL.*Username not supplied.*password not supplied.*"),
},
},
})
}
9 changes: 1 addition & 8 deletions templates/index.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,4 @@ generate the username/tokens for a user can be found [here](https://help.sonatyp

{{ tffile "examples/provider/provider.tf" }}

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `password` (String, Sensitive) Password for your Administrator user for Sonatype IQ Server
- `url` (String) Sonatype IQ Server URL
- `username` (String) Administrator Username for Sonatype IQ Server
{{ .SchemaMarkdown }}
Loading