Skip to content

Commit 0c07f47

Browse files
authored
add missing route fields to data source (#23)
Fixes https://linear.app/pomerium/issue/ENG-1836/terraform-provider-route-value-conversion-error also marks some properties that receive defaults on create `computed` so that the TF won't complain.
1 parent d436f6e commit 0c07f47

File tree

4 files changed

+226
-9
lines changed

4 files changed

+226
-9
lines changed

example/main.tf

+87-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
pomerium = {
44
source = "pomerium/pomerium"
5-
version = "0.0.1"
5+
version = "0.0.2"
66
}
77
}
88
}
@@ -68,6 +68,92 @@ resource "pomerium_key_pair" "test_key_pair" {
6868
key = file("test.host-key.pem")
6969
}
7070

71+
# Example route with prefix matching
72+
resource "pomerium_route" "prefix_route" {
73+
name = "prefix-route"
74+
namespace_id = pomerium_namespace.test_namespace.id
75+
from = "https://prefix.localhost.pomerium.io"
76+
to = ["https://target-service.internal"]
77+
prefix = "/api/"
78+
prefix_rewrite = "/v1/"
79+
policies = [pomerium_policy.test_policy.id]
80+
81+
timeout = "30s"
82+
idle_timeout = "5m"
83+
84+
set_request_headers = {
85+
"X-Custom-Header" = "custom-value"
86+
}
87+
remove_request_headers = ["Referer"]
88+
set_response_headers = {
89+
"Strict-Transport-Security" = "max-age=31536000"
90+
}
91+
92+
allow_websockets = true
93+
preserve_host_header = true
94+
pass_identity_headers = true
95+
}
96+
97+
# Example route with path matching
98+
resource "pomerium_route" "path_route" {
99+
name = "path-route"
100+
namespace_id = pomerium_namespace.test_namespace.id
101+
from = "https://path.localhost.pomerium.io"
102+
to = ["https://path-service.internal"]
103+
path = "/exact/path/match"
104+
105+
tls_skip_verify = true
106+
tls_upstream_server_name = "internal-name"
107+
tls_downstream_server_name = "external-name"
108+
}
109+
110+
# Example route with regex matching and rewriting
111+
resource "pomerium_route" "regex_route" {
112+
name = "regex-route"
113+
namespace_id = pomerium_namespace.test_namespace.id
114+
from = "https://regex.localhost.pomerium.io"
115+
to = ["https://regex-service.internal"]
116+
regex = "^/users/([0-9]+)/profile$"
117+
regex_rewrite_pattern = "^/users/([0-9]+)/profile$"
118+
regex_rewrite_substitution = "/api/v1/profiles/$1"
119+
regex_priority_order = 100
120+
}
121+
122+
# Example route with host rewriting
123+
resource "pomerium_route" "host_route" {
124+
name = "host-route"
125+
namespace_id = pomerium_namespace.test_namespace.id
126+
from = "https://host.localhost.pomerium.io"
127+
to = ["https://host-service.internal"]
128+
host_rewrite = "internal-host"
129+
host_path_regex_rewrite_pattern = "^/service/([^/]+)(/.*)$"
130+
host_path_regex_rewrite_substitution = "$1.internal$2"
131+
}
132+
133+
# Example route with OAuth/OIDC configuration
134+
resource "pomerium_route" "oauth_route" {
135+
name = "oauth-route"
136+
namespace_id = pomerium_namespace.test_namespace.id
137+
from = "https://oauth.localhost.pomerium.io"
138+
to = ["https://protected-service.internal"]
139+
140+
idp_client_id = "custom-client-id"
141+
idp_client_secret = "custom-client-secret"
142+
show_error_details = true
143+
}
144+
145+
# Example route with Kubernetes integration
146+
resource "pomerium_route" "kubernetes_route" {
147+
name = "kubernetes-route"
148+
namespace_id = pomerium_namespace.test_namespace.id
149+
from = "https://k8s.localhost.pomerium.io"
150+
to = ["https://kubernetes-service.internal"]
151+
152+
kubernetes_service_account_token = "eyJhbGciOiJS..."
153+
allow_spdy = true
154+
tls_upstream_allow_renegotiation = true
155+
}
156+
71157
# Data source examples
72158
data "pomerium_namespaces" "all_namespaces" {}
73159

internal/provider/route.go

+16-2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func (r *RouteResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
7676
"stat_name": schema.StringAttribute{
7777
Description: "Name of the stat.",
7878
Optional: true,
79+
Computed: true,
7980
},
8081
"prefix": schema.StringAttribute{
8182
Description: "Prefix.",
@@ -125,11 +126,13 @@ func (r *RouteResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
125126
Description: "Timeout.",
126127
Optional: true,
127128
CustomType: timetypes.GoDurationType{},
129+
Computed: true,
128130
},
129131
"idle_timeout": schema.StringAttribute{
130132
Description: "Idle timeout.",
131133
Optional: true,
132134
CustomType: timetypes.GoDurationType{},
135+
Computed: true,
133136
},
134137
"allow_websockets": schema.BoolAttribute{
135138
Description: "Allow websockets.",
@@ -193,6 +196,7 @@ func (r *RouteResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
193196
"show_error_details": schema.BoolAttribute{
194197
Description: "Show error details.",
195198
Optional: true,
199+
Computed: true,
196200
},
197201
},
198202
}
@@ -239,7 +243,11 @@ func (r *RouteResource) Create(ctx context.Context, req resource.CreateRequest,
239243
return
240244
}
241245

242-
plan.ID = types.StringValue(respRoute.Route.Id)
246+
diags = ConvertRouteFromPB(&plan, respRoute.Route)
247+
resp.Diagnostics.Append(diags...)
248+
if diags.HasError() {
249+
return
250+
}
243251

244252
tflog.Trace(ctx, "Created a route", map[string]interface{}{
245253
"id": plan.ID.ValueString(),
@@ -292,14 +300,20 @@ func (r *RouteResource) Update(ctx context.Context, req resource.UpdateRequest,
292300
return
293301
}
294302

295-
_, err := r.client.RouteService.SetRoute(ctx, &pb.SetRouteRequest{
303+
respRoute, err := r.client.RouteService.SetRoute(ctx, &pb.SetRouteRequest{
296304
Route: pbRoute,
297305
})
298306
if err != nil {
299307
resp.Diagnostics.AddError("set route", err.Error())
300308
return
301309
}
302310

311+
diags = ConvertRouteFromPB(&plan, respRoute.Route)
312+
resp.Diagnostics.Append(diags...)
313+
if diags.HasError() {
314+
return
315+
}
316+
303317
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
304318
}
305319

internal/provider/route_data_source.go

+122
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66

7+
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
78
"github.com/hashicorp/terraform-plugin-framework/datasource"
89
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
910
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -57,6 +58,127 @@ func (d *RouteDataSource) Schema(_ context.Context, _ datasource.SchemaRequest,
5758
ElementType: types.StringType,
5859
Description: "List of policy IDs associated with the route.",
5960
},
61+
"stat_name": schema.StringAttribute{
62+
Computed: true,
63+
Description: "Name of the stat.",
64+
},
65+
"prefix": schema.StringAttribute{
66+
Computed: true,
67+
Description: "Prefix.",
68+
},
69+
"path": schema.StringAttribute{
70+
Computed: true,
71+
Description: "Path.",
72+
},
73+
"regex": schema.StringAttribute{
74+
Computed: true,
75+
Description: "Regex.",
76+
},
77+
"prefix_rewrite": schema.StringAttribute{
78+
Computed: true,
79+
Description: "Prefix rewrite.",
80+
},
81+
"regex_rewrite_pattern": schema.StringAttribute{
82+
Computed: true,
83+
Description: "Regex rewrite pattern.",
84+
},
85+
"regex_rewrite_substitution": schema.StringAttribute{
86+
Computed: true,
87+
Description: "Regex rewrite substitution.",
88+
},
89+
"host_rewrite": schema.StringAttribute{
90+
Computed: true,
91+
Description: "Host rewrite.",
92+
},
93+
"host_rewrite_header": schema.StringAttribute{
94+
Computed: true,
95+
Description: "Host rewrite header.",
96+
},
97+
"host_path_regex_rewrite_pattern": schema.StringAttribute{
98+
Computed: true,
99+
Description: "Host path regex rewrite pattern.",
100+
},
101+
"host_path_regex_rewrite_substitution": schema.StringAttribute{
102+
Computed: true,
103+
Description: "Host path regex rewrite substitution.",
104+
},
105+
"regex_priority_order": schema.Int64Attribute{
106+
Computed: true,
107+
Description: "Regex priority order.",
108+
},
109+
"timeout": schema.StringAttribute{
110+
Computed: true,
111+
Description: "Timeout.",
112+
CustomType: timetypes.GoDurationType{},
113+
},
114+
"idle_timeout": schema.StringAttribute{
115+
Computed: true,
116+
Description: "Idle timeout.",
117+
CustomType: timetypes.GoDurationType{},
118+
},
119+
"allow_websockets": schema.BoolAttribute{
120+
Computed: true,
121+
Description: "Allow websockets.",
122+
},
123+
"allow_spdy": schema.BoolAttribute{
124+
Computed: true,
125+
Description: "Allow SPDY.",
126+
},
127+
"tls_skip_verify": schema.BoolAttribute{
128+
Computed: true,
129+
Description: "TLS skip verify.",
130+
},
131+
"tls_upstream_server_name": schema.StringAttribute{
132+
Computed: true,
133+
Description: "TLS upstream server name.",
134+
},
135+
"tls_downstream_server_name": schema.StringAttribute{
136+
Computed: true,
137+
Description: "TLS downstream server name.",
138+
},
139+
"tls_upstream_allow_renegotiation": schema.BoolAttribute{
140+
Computed: true,
141+
Description: "TLS upstream allow renegotiation.",
142+
},
143+
"set_request_headers": schema.MapAttribute{
144+
Computed: true,
145+
ElementType: types.StringType,
146+
Description: "Set request headers.",
147+
},
148+
"remove_request_headers": schema.ListAttribute{
149+
Computed: true,
150+
ElementType: types.StringType,
151+
Description: "Remove request headers.",
152+
},
153+
"set_response_headers": schema.MapAttribute{
154+
Computed: true,
155+
ElementType: types.StringType,
156+
Description: "Set response headers.",
157+
},
158+
"preserve_host_header": schema.BoolAttribute{
159+
Computed: true,
160+
Description: "Preserve host header.",
161+
},
162+
"pass_identity_headers": schema.BoolAttribute{
163+
Computed: true,
164+
Description: "Pass identity headers.",
165+
},
166+
"kubernetes_service_account_token": schema.StringAttribute{
167+
Computed: true,
168+
Description: "Kubernetes service account token.",
169+
},
170+
"idp_client_id": schema.StringAttribute{
171+
Computed: true,
172+
Description: "IDP client ID.",
173+
},
174+
"idp_client_secret": schema.StringAttribute{
175+
Computed: true,
176+
Description: "IDP client secret.",
177+
},
178+
"show_error_details": schema.BoolAttribute{
179+
Computed: true,
180+
Description: "Show error details.",
181+
},
60182
},
61183
}
62184
}

internal/provider/route_model.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,7 @@ func ConvertRouteFromPB(
117117
}
118118
dst.To = types.ListValueMust(types.StringType, toList)
119119

120-
policiesList := make([]attr.Value, len(src.PolicyIds))
121-
for i, v := range src.PolicyIds {
122-
policiesList[i] = types.StringValue(v)
123-
}
124-
dst.Policies = types.ListValueMust(types.StringType, policiesList)
125-
120+
dst.Policies = FromStringSlice(src.PolicyIds)
126121
dst.StatName = types.StringValue(src.StatName)
127122
dst.Prefix = types.StringPointerValue(src.Prefix)
128123
dst.Path = types.StringPointerValue(src.Path)

0 commit comments

Comments
 (0)