-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add opslevel_service_dependencies datasource (#429)
* add opslevel_service_dependencies datasource * add dependents to service dependencies datasource * Apply suggestions from code review Co-authored-by: Taimoor Ahmad <[email protected]> * code cleanup and azure fix from upstream update * add example for opslevel_service_dependencies datasource --------- Co-authored-by: Taimoor Ahmad <[email protected]>
- Loading branch information
1 parent
1ec246a
commit 87183cb
Showing
6 changed files
with
197 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
kind: Feature | ||
body: add opslevel_service_dependencies datasource | ||
time: 2024-08-08T16:11:07.119526-05:00 |
15 changes: 15 additions & 0 deletions
15
examples/data-sources/opslevel_service_dependencies/data-source.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
data "opslevel_service" "foo" { | ||
alias = "foo" | ||
} | ||
|
||
data "opslevel_service" "bar" { | ||
id = "Z2lkOi8vb3BzbGV2ZWwvU2VydmljZS84Njcw" | ||
} | ||
|
||
data "opslevel_service_dependencies" "by_alias" { | ||
service = data.opslevel_service.foo.alias | ||
} | ||
|
||
data "opslevel_service_dependencies" "by_id" { | ||
service = data.opslevel_service.bar.id | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
package opslevel | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework/datasource" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/path" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
"github.com/hashicorp/terraform-plugin-log/tflog" | ||
"github.com/opslevel/opslevel-go/v2024" | ||
) | ||
|
||
// Ensure ServiceDataSource implements DataSourceWithConfigure interface | ||
var _ datasource.DataSourceWithConfigure = &ServiceDataSource{} | ||
|
||
func NewServiceDependenciesDataSource() datasource.DataSource { | ||
return &ServiceDependenciesDataSource{} | ||
} | ||
|
||
// ServiceDataSource manages a Service data source. | ||
type ServiceDependenciesDataSource struct { | ||
CommonDataSourceClient | ||
} | ||
|
||
// ServiceDependenciesModel describes the data source data model. | ||
type ServiceDependenciesModel struct { | ||
Dependents []dependentsModel `tfsdk:"dependents"` | ||
Dependencies []dependenciesModel `tfsdk:"dependencies"` | ||
Service types.String `tfsdk:"service"` | ||
} | ||
|
||
type dependentsModel struct { | ||
Id types.String `tfsdk:"id"` | ||
Locked types.Bool `tfsdk:"locked"` | ||
Notes types.String `tfsdk:"notes"` | ||
} | ||
|
||
type dependenciesModel struct { | ||
Id types.String `tfsdk:"id"` | ||
Locked types.Bool `tfsdk:"locked"` | ||
Notes types.String `tfsdk:"notes"` | ||
} | ||
|
||
func NewServiceDependenciesModel(serviceIdentifier string, dependents []dependentsModel, dependencies []dependenciesModel) ServiceDependenciesModel { | ||
return ServiceDependenciesModel{ | ||
Dependents: dependents, | ||
Dependencies: dependencies, | ||
Service: types.StringValue(serviceIdentifier), | ||
} | ||
} | ||
|
||
func (d *ServiceDependenciesDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_service_dependencies" | ||
} | ||
|
||
var depsAttrs = map[string]schema.Attribute{ | ||
"id": schema.StringAttribute{ | ||
Description: "The ID of the service dependency.", | ||
Computed: true, | ||
}, | ||
"locked": schema.BoolAttribute{ | ||
Description: "Is the dependency locked by a service config?", | ||
Computed: true, | ||
}, | ||
"notes": schema.StringAttribute{ | ||
Description: "Notes for service dependency.", | ||
Optional: true, | ||
}, | ||
} | ||
|
||
func (d *ServiceDependenciesDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
Description: "Service Dependencies data source", | ||
|
||
Attributes: map[string]schema.Attribute{ | ||
"dependents": schema.ListNestedAttribute{ | ||
Description: "List of Service Dependents of a service", | ||
NestedObject: schema.NestedAttributeObject{ | ||
Attributes: depsAttrs, | ||
}, | ||
Computed: true, | ||
}, | ||
"dependencies": schema.ListNestedAttribute{ | ||
Description: "List of Service Dependencies of a service", | ||
NestedObject: schema.NestedAttributeObject{ | ||
Attributes: depsAttrs, | ||
}, | ||
Computed: true, | ||
}, | ||
"service": schema.StringAttribute{ | ||
Description: "The ID or alias of the service with the dependency.", | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func (d *ServiceDependenciesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var ( | ||
err error | ||
service *opslevel.Service | ||
serviceIdentifier string | ||
) | ||
|
||
// Read Terraform configuration data into the model | ||
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("service"), &serviceIdentifier)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// Retrieve Service | ||
if opslevel.IsID(serviceIdentifier) { | ||
service, err = d.client.GetService(opslevel.ID(serviceIdentifier)) | ||
} else { | ||
service, err = d.client.GetServiceWithAlias(serviceIdentifier) | ||
} | ||
if err != nil || service == nil { | ||
resp.Diagnostics.AddError("opslevel client error", fmt.Sprintf("Unable to read service, got error: %s", err)) | ||
return | ||
} | ||
|
||
dependenciesModel, err := getDependenciesModelOfService(d.client, service) | ||
if err != nil { | ||
resp.Diagnostics.AddError("opslevel client error", fmt.Sprintf("Unable to get dependencies for service, got error: %s", err)) | ||
return | ||
} | ||
|
||
dependentsModel, err := getDependentsModelOfService(d.client, service) | ||
if err != nil { | ||
resp.Diagnostics.AddError("opslevel client error", fmt.Sprintf("Unable to get dependents for service, got error: %s", err)) | ||
return | ||
} | ||
|
||
stateModel := NewServiceDependenciesModel(serviceIdentifier, dependentsModel, dependenciesModel) | ||
|
||
// Save data into Terraform state | ||
tflog.Trace(ctx, "read an OpsLevel Service Dependencies data source") | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &stateModel)...) | ||
} | ||
|
||
func getDependenciesModelOfService(client *opslevel.Client, service *opslevel.Service) ([]dependenciesModel, error) { | ||
dependencies := []dependenciesModel{} | ||
svcDependencies, err := service.GetDependencies(client, nil) | ||
if err != nil || svcDependencies == nil { | ||
return dependencies, err | ||
} | ||
|
||
for _, svcDependency := range svcDependencies.Edges { | ||
dependencies = append(dependencies, dependenciesModel{ | ||
Locked: types.BoolValue(svcDependency.Locked), | ||
Id: ComputedStringValue(string(svcDependency.Id)), | ||
Notes: ComputedStringValue(svcDependency.Notes), | ||
}) | ||
} | ||
return dependencies, nil | ||
} | ||
|
||
func getDependentsModelOfService(client *opslevel.Client, service *opslevel.Service) ([]dependentsModel, error) { | ||
dependents := []dependentsModel{} | ||
svcDependents, err := service.GetDependents(client, nil) | ||
if err != nil || svcDependents == nil { | ||
return dependents, err | ||
} | ||
|
||
for _, svcDependent := range svcDependents.Edges { | ||
dependents = append(dependents, dependentsModel{ | ||
Locked: types.BoolValue(svcDependent.Locked), | ||
Id: ComputedStringValue(string(svcDependent.Id)), | ||
Notes: ComputedStringValue(svcDependent.Notes), | ||
}) | ||
} | ||
return dependents, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule opslevel-go
updated
21 files
+0 −3 | .changes/unreleased/Dependency-20240723-155713.yaml | |
+0 −4 | .changes/unreleased/Feature-20240722-152338.yaml | |
+3 −0 | .changes/unreleased/Feature-20240808-123025.yaml | |
+3 −0 | .changes/unreleased/Refactor-20240807-122518.yaml | |
+8 −0 | .changes/v2024.8.1.md | |
+9 −0 | CHANGELOG.md | |
+10 −1 | Taskfile.yml | |
+2 −2 | cache_test.go | |
+6 −0 | check.go | |
+34 −0 | check_package_version.go | |
+3 −2 | check_service_property.go | |
+75 −6 | check_test.go | |
+92 −2 | enum.go | |
+5 −1 | gen.go | |
+2 −2 | infra.go | |
+4 −4 | infra_test.go | |
+61 −4 | input.go | |
+80 −0 | integration.go | |
+170 −8 | integration_test.go | |
+5 −2 | interfaces.go | |
+1 −1 | version.go |