Skip to content

Commit 3b62cc8

Browse files
committed
feat: replace host/port/portol fields with singe api_base_url
1 parent 7651fcf commit 3b62cc8

File tree

3 files changed

+43
-103
lines changed

3 files changed

+43
-103
lines changed

docs/index.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,7 @@ terraform {
4545
}
4646
4747
provider "semaphoreui" {
48-
hostname = "example.com"
49-
port = 3000 # Default: 3000
50-
path = "/api" # Default: "/api"
51-
protocol = "http" # Default: "https"
48+
api_base_url = "http://localhost:3000/api"
5249
api_token = "your token"
5350
}
5451
```
@@ -58,9 +55,6 @@ provider "semaphoreui" {
5855

5956
### Optional
6057

58+
- `api_base_url` (String)
6159
- `api_token` (String, Sensitive) SemaphoreUI API token. This can also be defined by the `SEMAPHOREUI_API_TOKEN` environment variable.
62-
- `hostname` (String) SemaphoreUI API hostname. This can also be defined by the `SEMAPHOREUI_HOSTNAME` environment variable. Example: `example.com`.
63-
- `path` (String) SemaphoreUI API base path. This can also be defined by the `SEMAPHOREUI_PATH` environment variable. Default: `/api`.
64-
- `port` (Number) SemaphoreUI API port. This can also be defined by the `SEMAPHOREUI_PORT` environment variable. Default: `3000`.
65-
- `protocol` (String) SemaphoreUI API protocol. This can also be defined by the `SEMAPHOREUI_PROTOCOL` environment variable. Must be one of `http` or `https`. Default: `https`.
6660
- `tls_skip_verify` (Boolean) Skip TLS verification for the SemaphoreUI API when using https. This can also be defined by the `SEMAPHOREUI_TLS_SKIP_VERIFY` environment variable. Default: `false`.

examples/provider/provider.tf

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ terraform {
99
}
1010

1111
provider "semaphoreui" {
12-
hostname = "example.com"
13-
port = 3000 # Default: 3000
14-
path = "/api" # Default: "/api"
15-
protocol = "http" # Default: "https"
12+
api_base_url = "http://localhost:3000/api" # Default: "http://localhost:3000/api"
1613
api_token = "your token"
1714
}

internal/provider/provider.go

Lines changed: 40 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,21 @@ package provider
33
import (
44
"context"
55
"crypto/tls"
6-
"fmt"
6+
"net/http"
7+
"net/url"
8+
"os"
9+
"strconv"
10+
apiclient "terraform-provider-semaphoreui/semaphoreui/client"
11+
712
httptransport "github.com/go-openapi/runtime/client"
813
"github.com/go-openapi/strfmt"
9-
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
1014
"github.com/hashicorp/terraform-plugin-framework/datasource"
1115
"github.com/hashicorp/terraform-plugin-framework/function"
1216
"github.com/hashicorp/terraform-plugin-framework/path"
1317
"github.com/hashicorp/terraform-plugin-framework/provider"
1418
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
1519
"github.com/hashicorp/terraform-plugin-framework/resource"
16-
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1720
"github.com/hashicorp/terraform-plugin-framework/types"
18-
"net/http"
19-
"os"
20-
"strconv"
21-
apiclient "terraform-provider-semaphoreui/semaphoreui/client"
2221
)
2322

2423
var _ provider.Provider = &SemaphoreUIProvider{}
@@ -34,12 +33,9 @@ type SemaphoreUIProvider struct {
3433

3534
// SemaphoreUIProviderModel describes the provider data model.
3635
type SemaphoreUIProviderModel struct {
37-
Hostname types.String `tfsdk:"hostname"`
38-
Port types.Int32 `tfsdk:"port"`
39-
Path types.String `tfsdk:"path"`
40-
Protocol types.String `tfsdk:"protocol"`
4136
ApiToken types.String `tfsdk:"api_token"`
4237
TlsSkipVerify types.Bool `tfsdk:"tls_skip_verify"`
38+
ApiBaseUrl types.String `tfsdk:"api_base_url"`
4339
}
4440

4541
func (p *SemaphoreUIProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
@@ -64,30 +60,15 @@ fetch("/api/user/tokens", {
6460
The token will be printed in the console. This token will grant the same level of access as the logged in user. Copy the token value and use it to configure the provider. The token is sensitive and should be treated as a secret. It is recommended to use the ` + "`SEMAPHOREUI_API_TOKEN`" + ` environment variable to configure the provider.
6561
`,
6662
Attributes: map[string]schema.Attribute{
67-
"hostname": schema.StringAttribute{
68-
MarkdownDescription: "SemaphoreUI API hostname. This can also be defined by the `SEMAPHOREUI_HOSTNAME` environment variable. Example: `example.com`.",
69-
Optional: true,
70-
},
71-
"port": schema.Int32Attribute{
72-
MarkdownDescription: "SemaphoreUI API port. This can also be defined by the `SEMAPHOREUI_PORT` environment variable. Default: `3000`.",
73-
Optional: true,
74-
},
75-
"path": schema.StringAttribute{
76-
MarkdownDescription: "SemaphoreUI API base path. This can also be defined by the `SEMAPHOREUI_PATH` environment variable. Default: `/api`.",
77-
Optional: true,
78-
},
79-
"protocol": schema.StringAttribute{
80-
MarkdownDescription: "SemaphoreUI API protocol. This can also be defined by the `SEMAPHOREUI_PROTOCOL` environment variable. Must be one of `http` or `https`. Default: `https`.",
81-
Optional: true,
82-
Validators: []validator.String{
83-
stringvalidator.OneOf("http", "https"),
84-
},
85-
},
8663
"api_token": schema.StringAttribute{
8764
MarkdownDescription: "SemaphoreUI API token. This can also be defined by the `SEMAPHOREUI_API_TOKEN` environment variable.",
8865
Sensitive: true,
8966
Optional: true,
9067
},
68+
"api_base_url": schema.StringAttribute{
69+
MarkdownDescription: "SemaphoreUI API base URL. This can also be defined by the `SEMAPHOREUI_API_BASE_URL` environment variable. Default: `http://localhost:3000/api`.",
70+
Optional: true,
71+
},
9172
"tls_skip_verify": schema.BoolAttribute{
9273
MarkdownDescription: "Skip TLS verification for the SemaphoreUI API when using https. This can also be defined by the `SEMAPHOREUI_TLS_SKIP_VERIFY` environment variable. Default: `false`.",
9374
Optional: true,
@@ -105,39 +86,12 @@ func (p *SemaphoreUIProvider) Configure(ctx context.Context, req provider.Config
10586
return
10687
}
10788

108-
if config.Hostname.IsUnknown() {
109-
resp.Diagnostics.AddAttributeError(
110-
path.Root("hostname"),
111-
"Unknown SemaphoreUI API Hostname",
112-
"The provider cannot create the SemaphoreUI API client as there is an unknown configuration value for the SemaphoreUI API hostname. "+
113-
"Either target apply the source of the value first, set the value statically in the configuration, or use the SEMAPHOREUI_HOSTNAME environment variable.",
114-
)
115-
}
116-
117-
if config.Port.IsUnknown() {
118-
resp.Diagnostics.AddAttributeError(
119-
path.Root("port"),
120-
"Unknown SemaphoreUI API Port",
121-
"The provider cannot create the SemaphoreUI API client as there is an unknown configuration value for the SemaphoreUI API port. "+
122-
"Either target apply the source of the value first, set the value statically in the configuration, or use the SEMAPHOREUI_PORT environment variable.",
123-
)
124-
}
125-
126-
if config.Path.IsUnknown() {
127-
resp.Diagnostics.AddAttributeError(
128-
path.Root("path"),
129-
"Unknown SemaphoreUI API Path",
130-
"The provider cannot create the SemaphoreUI API client as there is an unknown configuration value for the SemaphoreUI API path. "+
131-
"Either target apply the source of the value first, set the value statically in the configuration, or use the SEMAPHOREUI_PATH environment variable.",
132-
)
133-
}
134-
135-
if config.Protocol.IsUnknown() {
89+
if config.ApiToken.IsUnknown() {
13690
resp.Diagnostics.AddAttributeError(
137-
path.Root("protocol"),
138-
"Unknown SemaphoreUI API Protocol",
139-
"The provider cannot create the SemaphoreUI API client as there is an unknown configuration value for the SemaphoreUI API protocol. "+
140-
"Either target apply the source of the value first, set the value statically in the configuration, or use the SEMAPHOREUI_PROTOCOL environment variable.",
91+
path.Root("api_token"),
92+
"Unknown SemaphoreUI API Token",
93+
"The provider cannot create the SemaphoreUI API client as there is an unknown configuration value for the SemaphoreUI API token. "+
94+
"Either target apply the source of the value first, set the value statically in the configuration, or use the SEMAPHOREUI_API_TOKEN environment variable.",
14195
)
14296
}
14397

@@ -165,24 +119,12 @@ func (p *SemaphoreUIProvider) Configure(ctx context.Context, req provider.Config
165119

166120
// Default values to environment variables, but override
167121
// with Terraform configuration value if set.
168-
hostname := os.Getenv("SEMAPHOREUI_HOSTNAME")
169-
port := os.Getenv("SEMAPHOREUI_PORT")
170-
basePath := os.Getenv("SEMAPHOREUI_PATH")
171-
protocol := os.Getenv("SEMAPHOREUI_PROTOCOL")
172122
apiToken := os.Getenv("SEMAPHOREUI_API_TOKEN")
123+
apiBaseUrl := os.Getenv("SEMAPHOREUI_API_BASE_URL")
173124
tlsSkipVerify := os.Getenv("SEMAPHOREUI_TLS_SKIP_VERIFY")
174125

175-
if !config.Hostname.IsNull() {
176-
hostname = config.Hostname.ValueString()
177-
}
178-
if !config.Port.IsNull() {
179-
port = strconv.Itoa(int(config.Port.ValueInt32()))
180-
}
181-
if !config.Path.IsNull() {
182-
basePath = config.Path.ValueString()
183-
}
184-
if !config.Protocol.IsNull() {
185-
protocol = config.Protocol.ValueString()
126+
if !config.ApiBaseUrl.IsNull() {
127+
apiBaseUrl = config.ApiBaseUrl.ValueString()
186128
}
187129
if !config.ApiToken.IsNull() {
188130
apiToken = config.ApiToken.ValueString()
@@ -193,11 +135,11 @@ func (p *SemaphoreUIProvider) Configure(ctx context.Context, req provider.Config
193135

194136
// If any of the expected configurations are missing, use defaults or return
195137
// errors with provider-specific guidance.
196-
if hostname == "" {
138+
if apiBaseUrl == "" {
197139
resp.Diagnostics.AddAttributeError(
198-
path.Root("hostname"),
199-
"Missing SemaphoreUI API Hostname",
200-
"Set the host value in the configuration or use the SEMAPHOREUI_HOSTNAME environment variable. "+
140+
path.Root("api_base_url"),
141+
"Missing SemaphoreUI API base URL",
142+
"Set the host value in the configuration or use the SEMAPHOREUI_API_BASE_URL environment variable. "+
201143
"If either is already set, ensure the value is not empty.",
202144
)
203145
}
@@ -211,29 +153,36 @@ func (p *SemaphoreUIProvider) Configure(ctx context.Context, req provider.Config
211153
)
212154
}
213155

214-
if port == "" {
215-
port = "3000" // Default
216-
}
217-
if protocol == "" {
218-
protocol = "https" // Default
219-
}
220-
if basePath == "" {
221-
basePath = "/api" // Default
156+
if apiBaseUrl == "" {
157+
apiBaseUrl = "http://localhost:3000/api" // Default
222158
}
159+
223160
if tlsSkipVerify == "" {
224161
tlsSkipVerify = "false" // Default
225162
}
226163

227164
if resp.Diagnostics.HasError() {
228165
return
229166
}
167+
168+
u, err := url.Parse(apiBaseUrl)
169+
if err != nil {
170+
resp.Diagnostics.AddAttributeError(
171+
path.Root("api_base_url"),
172+
"Invalid SemaphoreUI API base URL",
173+
"The provider cannot create the SemaphoreUI API client as the API base URL is invalid. "+
174+
"Either target apply the source of the value first, set the value statically in the configuration, or use the SEMAPHOREUI_API_BASE_URL environment variable.",
175+
)
176+
return
177+
}
178+
230179
var rt *httptransport.Runtime
231180
if tlsSkipVerify == "true" {
232181
transport := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
233182
httpClient := &http.Client{Transport: transport}
234-
rt = httptransport.NewWithClient(fmt.Sprintf("%s:%s", hostname, port), basePath, []string{protocol}, httpClient)
183+
rt = httptransport.NewWithClient(u.Host, u.Path, []string{u.Scheme}, httpClient)
235184
} else {
236-
rt = httptransport.New(fmt.Sprintf("%s:%s", hostname, port), basePath, []string{protocol})
185+
rt = httptransport.New(u.Host, u.Path, []string{u.Scheme})
237186
}
238187
rt.DefaultAuthentication = httptransport.BearerToken(apiToken)
239188

0 commit comments

Comments
 (0)