Skip to content

Commit b3b9617

Browse files
committed
(feat): Add data sources for all resources, and add service account resource.
1 parent c6cf19d commit b3b9617

7 files changed

+721
-10
lines changed

example/main.tf

+24-9
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,15 @@ provider "pomerium" {
1414
shared_secret_b64 = "9OkZR6hwfmVD3a7Sfmgq58lUbFJGGz4hl/R9xbHFCAg="
1515
}
1616

17-
# resource "pomerium_namespace" "test_namespace" {
18-
# name = "test-namespace"
19-
# parent_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
20-
# }
21-
22-
locals {
23-
namespace_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
17+
# Create resources
18+
resource "pomerium_namespace" "test_namespace" {
19+
name = "test-namespace"
20+
parent_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
2421
}
2522

2623
resource "pomerium_policy" "test_policy" {
2724
name = "test-policy"
28-
namespace_id = local.namespace_id
25+
namespace_id = pomerium_namespace.test_namespace.id
2926
ppl = <<EOF
3027
- allow:
3128
and:
@@ -35,8 +32,26 @@ EOF
3532

3633
resource "pomerium_route" "test_route" {
3734
name = "test-route"
38-
namespace_id = local.namespace_id
35+
namespace_id = pomerium_namespace.test_namespace.id
3936
from = "https://verify-tf.localhost.pomerium.io"
4037
to = ["https://verify.pomerium.com"]
4138
policies = [pomerium_policy.test_policy.id]
4239
}
40+
41+
# Data source examples
42+
data "pomerium_namespace" "existing_namespace" {
43+
id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
44+
}
45+
46+
data "pomerium_route" "existing_route" {
47+
id = pomerium_route.test_route.id
48+
}
49+
50+
# Output examples
51+
output "namespace_name" {
52+
value = data.pomerium_namespace.existing_namespace.name
53+
}
54+
55+
output "route_from" {
56+
value = data.pomerium_route.existing_route.from
57+
}
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/datasource"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
11+
client "github.com/pomerium/enterprise-client-go"
12+
"github.com/pomerium/enterprise-client-go/pb"
13+
)
14+
15+
var _ datasource.DataSource = &NamespaceDataSource{}
16+
17+
func NewNamespaceDataSource() datasource.DataSource {
18+
return &NamespaceDataSource{}
19+
}
20+
21+
type NamespaceDataSource struct {
22+
client *client.Client
23+
}
24+
25+
type NamespaceDataSourceModel struct {
26+
ID types.String `tfsdk:"id"`
27+
Name types.String `tfsdk:"name"`
28+
ParentID types.String `tfsdk:"parent_id"`
29+
}
30+
31+
func (d *NamespaceDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
32+
resp.TypeName = req.ProviderTypeName + "_namespace"
33+
}
34+
35+
func (d *NamespaceDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
36+
resp.Schema = schema.Schema{
37+
MarkdownDescription: "Namespace data source",
38+
39+
Attributes: map[string]schema.Attribute{
40+
"id": schema.StringAttribute{
41+
Required: true,
42+
Description: "Unique identifier for the namespace.",
43+
},
44+
"name": schema.StringAttribute{
45+
Computed: true,
46+
Description: "Name of the namespace.",
47+
},
48+
"parent_id": schema.StringAttribute{
49+
Computed: true,
50+
Description: "ID of the parent namespace.",
51+
},
52+
},
53+
}
54+
}
55+
56+
func (d *NamespaceDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
57+
if req.ProviderData == nil {
58+
return
59+
}
60+
61+
client, ok := req.ProviderData.(*client.Client)
62+
if !ok {
63+
resp.Diagnostics.AddError(
64+
"Unexpected Data Source Configure Type",
65+
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
66+
)
67+
return
68+
}
69+
70+
d.client = client
71+
}
72+
73+
func (d *NamespaceDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
74+
var data NamespaceDataSourceModel
75+
76+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
77+
if resp.Diagnostics.HasError() {
78+
return
79+
}
80+
81+
namespaceResp, err := d.client.NamespaceService.GetNamespace(ctx, &pb.GetNamespaceRequest{
82+
Id: data.ID.ValueString(),
83+
})
84+
if err != nil {
85+
resp.Diagnostics.AddError("Error reading namespace", err.Error())
86+
return
87+
}
88+
89+
diags := ConvertNamespaceFromPB(&NamespaceResourceModel{
90+
ID: data.ID,
91+
Name: data.Name,
92+
ParentID: data.ParentID,
93+
}, namespaceResp.Namespace)
94+
resp.Diagnostics.Append(diags...)
95+
if resp.Diagnostics.HasError() {
96+
return
97+
}
98+
99+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
100+
}
+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/datasource"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
11+
client "github.com/pomerium/enterprise-client-go"
12+
"github.com/pomerium/enterprise-client-go/pb"
13+
)
14+
15+
var _ datasource.DataSource = &PolicyDataSource{}
16+
17+
func NewPolicyDataSource() datasource.DataSource {
18+
return &PolicyDataSource{}
19+
}
20+
21+
type PolicyDataSource struct {
22+
client *client.Client
23+
}
24+
25+
type PolicyDataSourceModel struct {
26+
ID types.String `tfsdk:"id"`
27+
Name types.String `tfsdk:"name"`
28+
NamespaceID types.String `tfsdk:"namespace_id"`
29+
PPL types.String `tfsdk:"ppl"`
30+
}
31+
32+
func (d *PolicyDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
33+
resp.TypeName = req.ProviderTypeName + "_policy"
34+
}
35+
36+
func (d *PolicyDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
37+
resp.Schema = schema.Schema{
38+
MarkdownDescription: "Policy data source",
39+
40+
Attributes: map[string]schema.Attribute{
41+
"id": schema.StringAttribute{
42+
Required: true,
43+
Description: "Unique identifier for the policy.",
44+
},
45+
"name": schema.StringAttribute{
46+
Computed: true,
47+
Description: "Name of the policy.",
48+
},
49+
"namespace_id": schema.StringAttribute{
50+
Computed: true,
51+
Description: "ID of the namespace the policy belongs to.",
52+
},
53+
"ppl": schema.StringAttribute{
54+
Computed: true,
55+
Description: "Policy Policy Language (PPL) string.",
56+
},
57+
},
58+
}
59+
}
60+
61+
func (d *PolicyDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
62+
if req.ProviderData == nil {
63+
return
64+
}
65+
66+
client, ok := req.ProviderData.(*client.Client)
67+
if !ok {
68+
resp.Diagnostics.AddError(
69+
"Unexpected Data Source Configure Type",
70+
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
71+
)
72+
return
73+
}
74+
75+
d.client = client
76+
}
77+
78+
func (d *PolicyDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
79+
var data PolicyDataSourceModel
80+
81+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
82+
if resp.Diagnostics.HasError() {
83+
return
84+
}
85+
86+
policyResp, err := d.client.PolicyService.GetPolicy(ctx, &pb.GetPolicyRequest{
87+
Id: data.ID.ValueString(),
88+
})
89+
if err != nil {
90+
resp.Diagnostics.AddError("Error reading policy", err.Error())
91+
return
92+
}
93+
94+
diags := ConvertPolicyFromPB(&PolicyResourceModel{
95+
ID: data.ID,
96+
Name: data.Name,
97+
NamespaceID: data.NamespaceID,
98+
PPL: data.PPL,
99+
}, policyResp.Policy)
100+
resp.Diagnostics.Append(diags...)
101+
if resp.Diagnostics.HasError() {
102+
return
103+
}
104+
105+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
106+
}

internal/provider/provider.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,17 @@ func (p *PomeriumProvider) Resources(_ context.Context) []func() resource.Resour
122122
NewNamespaceResource,
123123
NewRouteResource,
124124
NewPolicyResource,
125+
NewServiceAccountResource,
125126
}
126127
}
127128

128129
func (p *PomeriumProvider) DataSources(_ context.Context) []func() datasource.DataSource {
129-
return []func() datasource.DataSource{}
130+
return []func() datasource.DataSource{
131+
NewServiceAccountDataSource,
132+
NewRouteDataSource,
133+
NewNamespaceDataSource,
134+
NewPolicyDataSource,
135+
}
130136
}
131137

132138
func (p *PomeriumProvider) Functions(_ context.Context) []func() function.Function {
+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/datasource"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
11+
client "github.com/pomerium/enterprise-client-go"
12+
"github.com/pomerium/enterprise-client-go/pb"
13+
)
14+
15+
var _ datasource.DataSource = &RouteDataSource{}
16+
17+
func NewRouteDataSource() datasource.DataSource {
18+
return &RouteDataSource{}
19+
}
20+
21+
type RouteDataSource struct {
22+
client *client.Client
23+
}
24+
25+
type RouteDataSourceModel struct {
26+
ID types.String `tfsdk:"id"`
27+
Name types.String `tfsdk:"name"`
28+
From types.String `tfsdk:"from"`
29+
To types.List `tfsdk:"to"`
30+
NamespaceID types.String `tfsdk:"namespace_id"`
31+
Policies types.List `tfsdk:"policies"`
32+
}
33+
34+
func (d *RouteDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
35+
resp.TypeName = req.ProviderTypeName + "_route"
36+
}
37+
38+
func (d *RouteDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
39+
resp.Schema = schema.Schema{
40+
MarkdownDescription: "Route data source",
41+
42+
Attributes: map[string]schema.Attribute{
43+
"id": schema.StringAttribute{
44+
Required: true,
45+
Description: "Unique identifier for the route.",
46+
},
47+
"name": schema.StringAttribute{
48+
Computed: true,
49+
Description: "Name of the route.",
50+
},
51+
"from": schema.StringAttribute{
52+
Computed: true,
53+
Description: "From URL.",
54+
},
55+
"to": schema.ListAttribute{
56+
Computed: true,
57+
ElementType: types.StringType,
58+
Description: "To URLs.",
59+
},
60+
"namespace_id": schema.StringAttribute{
61+
Computed: true,
62+
Description: "ID of the namespace the route belongs to.",
63+
},
64+
"policies": schema.ListAttribute{
65+
Computed: true,
66+
ElementType: types.StringType,
67+
Description: "List of policy IDs associated with the route.",
68+
},
69+
},
70+
}
71+
}
72+
73+
func (d *RouteDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
74+
if req.ProviderData == nil {
75+
return
76+
}
77+
78+
client, ok := req.ProviderData.(*client.Client)
79+
if !ok {
80+
resp.Diagnostics.AddError(
81+
"Unexpected Data Source Configure Type",
82+
fmt.Sprintf("Expected *client.Client, got: %T.", req.ProviderData),
83+
)
84+
return
85+
}
86+
87+
d.client = client
88+
}
89+
90+
func (d *RouteDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
91+
var data RouteDataSourceModel
92+
93+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
94+
if resp.Diagnostics.HasError() {
95+
return
96+
}
97+
98+
routeResp, err := d.client.RouteService.GetRoute(ctx, &pb.GetRouteRequest{
99+
Id: data.ID.ValueString(),
100+
})
101+
if err != nil {
102+
resp.Diagnostics.AddError("Error reading route", err.Error())
103+
return
104+
}
105+
106+
diags := ConvertRouteFromPB(&RouteResourceModel{
107+
ID: data.ID,
108+
Name: data.Name,
109+
From: data.From,
110+
To: data.To,
111+
NamespaceID: data.NamespaceID,
112+
Policies: data.Policies,
113+
}, routeResp.Route)
114+
resp.Diagnostics.Append(diags...)
115+
if resp.Diagnostics.HasError() {
116+
return
117+
}
118+
119+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
120+
}

0 commit comments

Comments
 (0)