Skip to content

Commit

Permalink
Run acceptance tests only when 'acceptance' go:build tag is present
Browse files Browse the repository at this point in the history
  • Loading branch information
Bogdan Guranda committed May 8, 2024
1 parent ab00968 commit 7242ece
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 50 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ lint-fix: $(GOLANGCI_LINT)

.PHONY: test
test:
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
go test ./... -v $(TESTARGS) -timeout 120m

.PHONY: plugin
plugin:
Expand Down
11 changes: 11 additions & 0 deletions docs/data-sources/type.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,18 @@ description: |-

Type data source

Enables you to read any type of Cisco Observability Platform. Types are just schemas for the objects.
Type name is the field required to get the type data source.

## Example usage

In this example we want to fetch a type called fmm:namespace.

```terraform
data "observability_type" "ns" {
type_name = "fmm:namespace"
}
```

<!-- schema generated by tfplugindocs -->
## Schema
Expand Down
41 changes: 40 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,50 @@ description: |-
---

# observability Provider
# Observability Provider

Terraform Observability provider enables users to provision objects as resources and read types as data sources

## Authentication

To start using the Observability Terraform Provider you need to authenticate with the Cisco Observability Platform.

You can do this by either using service-principal or oauth as an authentication method:


```terraform
terraform {
required_providers {
observability = {
source = "registry.terraform.io/cisco-open/observability"
}
}
}
provider "observability" {
tenant = "<your cisco observability account>"
auth_method = "service-principal"
url = "https://<your environment/host>"
secrets_file = "<path to your secrets file>"
}
```

```terraform
terraform {
required_providers {
observability = {
source = "registry.terraform.io/cisco-open/observability"
}
}
}
provider "observability" {
tenant = "<your cisco observability account>"
auth_method = "oauth"
url = "https://<your environment/host>"
}
```

<!-- schema generated by tfplugindocs -->
## Schema
Expand Down
21 changes: 20 additions & 1 deletion docs/resources/object.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,26 @@ description: |-

Object resource


Enables you to create and manage any object of Cisco Observability Platform. Objects are actual populated values of a type. Data is a field which acts like a container for any object payload.

## Example usage

```terraform
resource "observability_object" "conn" {
type_name = "<your type>"
object_id = "<object id of the object>"
layer_type = "TENANT"
layer_id = "<your tenant>"
import_id = "<object type>|<object id>|TENANT|<your tenant>"
data = jsonencode(
{
"field1" : "value1",
"field2" : "value2",
...
}
)
}
```

<!-- schema generated by tfplugindocs -->
## Schema
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,30 @@ import (
)

// Ensure provider defined types fully satisfy framework interfaces.
var _ datasource.DataSource = &TypeDataSource{}
var _ datasource.DataSource = &KnowledgeTypeDataSource{}

func NewTypeDataSource() datasource.DataSource {
return &TypeDataSource{}
func NewKnowledgeTypeDataSource() datasource.DataSource {
return &KnowledgeTypeDataSource{}
}

// TypeDataSource defines the data source implementation.
type TypeDataSource struct {
// KnowledgeTypeDataSource defines the data source implementation.
type KnowledgeTypeDataSource struct {
client *api.AppdClient
}

// TypeDataSourceModel describes the data source data model.
type TypeDataSourceModel struct {
// KnowledgeTypeDataSourceModel describes the data source data model.
type KnowledgeTypeDataSourceModel struct {
Typename types.String `tfsdk:"type_name"`
Data types.Dynamic `tfsdk:"data"`
ID types.String `tfsdk:"id"`
}

func (d *TypeDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
func (d *KnowledgeTypeDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_type"
}

// Schema defines the schema for the data source.
func (d *TypeDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
func (d *KnowledgeTypeDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
// This description is used by the documentation generator and the language server.
MarkdownDescription: "Type data source",
Expand All @@ -61,7 +61,7 @@ func (d *TypeDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, r
}
}

func (d *TypeDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
func (d *KnowledgeTypeDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
Expand All @@ -80,8 +80,8 @@ func (d *TypeDataSource) Configure(_ context.Context, req datasource.ConfigureRe
}

//nolint:gocritic // Terraform framework requires the method signature to be as is
func (d *TypeDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data TypeDataSourceModel
func (d *KnowledgeTypeDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data KnowledgeTypeDataSourceModel

// Read Terraform configuration data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@
//
// SPDX-License-Identifier: MPL-2.0

//go:build acceptance

package provider

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

//lint:ignore U1000 Ignore unused function temporarily for debugging
func _TestAccTypeDataSource(t *testing.T) {
func TestAccKnowledgeTypeDataSource(t *testing.T) {
fmt.Print("DNSAJDANSJDANSJDNAJSDNJASDNJANJSNDJASNDJA")
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
Expand Down
4 changes: 2 additions & 2 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,13 +266,13 @@ func (p *COPProvider) Configure(ctx context.Context, req provider.ConfigureReque

func (p *COPProvider) Resources(_ context.Context) []func() resource.Resource {
return []func() resource.Resource{
NewObjectResource,
NewKnowledgeObjectResource,
}
}

func (p *COPProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
NewTypeDataSource,
NewKnowledgeTypeDataSource,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//
// SPDX-License-Identifier: MPL-2.0

//go:build acceptance

package provider

import (
Expand All @@ -16,7 +18,7 @@ const (
terraform {
required_providers {
observability = {
source = "testTerraform.com/appd/observability"
source = "registry.terraform.io/cisco-open/observability",
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ import (
)

// Ensure provider defined types fully satisfy framework interfaces.
var _ resource.Resource = &ObjectResource{}
var _ resource.ResourceWithImportState = &ObjectResource{}
var _ resource.Resource = &KnowledgeObjectResource{}
var _ resource.ResourceWithImportState = &KnowledgeObjectResource{}

func NewObjectResource() resource.Resource {
return &ObjectResource{}
func NewKnowledgeObjectResource() resource.Resource {
return &KnowledgeObjectResource{}
}

// ObjectResource defines the resource implementation.
type ObjectResource struct {
// KnowledgeObjectResource defines the resource implementation.
type KnowledgeObjectResource struct {
client *api.AppdClient
}

// ObjectResourceModel describes the resource data model.
type ObjectResourceModel struct {
// KnowledgeObjectResourceModel describes the resource data model.
type KnowledgeObjectResourceModel struct {
TypeName types.String `tfsdk:"type_name"`
ObjectID types.String `tfsdk:"object_id"`
LayerID types.String `tfsdk:"layer_id"`
Expand All @@ -43,12 +43,12 @@ type ObjectResourceModel struct {
ID types.String `tfsdk:"id"`
}

func (r *ObjectResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
func (r *KnowledgeObjectResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_object"
}

// Schema defines the schema for the resource.
func (r *ObjectResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
func (r *KnowledgeObjectResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
// This description is used by the documentation generator and the language server.
MarkdownDescription: "Object resource",
Expand Down Expand Up @@ -89,7 +89,7 @@ func (r *ObjectResource) Schema(_ context.Context, _ resource.SchemaRequest, res
}
}

func (r *ObjectResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
func (r *KnowledgeObjectResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
Expand All @@ -108,9 +108,9 @@ func (r *ObjectResource) Configure(_ context.Context, req resource.ConfigureRequ
}

//nolint:gocritic // Terraform framework requires the method signature to be as is
func (r *ObjectResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
func (r *KnowledgeObjectResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
tflog.Debug(ctx, "Create method invoked")
var data ObjectResourceModel
var data KnowledgeObjectResourceModel

// Read Terraform plan data into the model
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
Expand Down Expand Up @@ -145,10 +145,10 @@ func (r *ObjectResource) Create(ctx context.Context, req resource.CreateRequest,
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

//nolint:gocritic // Terraform framework requires the method signature to be as is
func (r *ObjectResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
//nolint:gocritic,funlen // Terraform framework requires the method signature to be as is
func (r *KnowledgeObjectResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
tflog.Debug(ctx, "Read method invoked")
var data ObjectResourceModel
var data KnowledgeObjectResourceModel
var importIDTokenLength = 4

// Read Terraform prior state data into the model
Expand Down Expand Up @@ -179,6 +179,13 @@ func (r *ObjectResource) Read(ctx context.Context, req resource.ReadRequest, res
layerID = identityFields[3]
}

tflog.Debug(ctx, fmt.Sprintf("type name is %s", typeName))
tflog.Debug(ctx, fmt.Sprintf("object id is %s", objID))
tflog.Debug(ctx, fmt.Sprintf("layer ID is %s", layerID))
tflog.Debug(ctx, fmt.Sprintf("layer type %s", layerType))
tflog.Debug(ctx, fmt.Sprintf("data payload %s", currentDataPayload))
tflog.Debug(ctx, fmt.Sprintf("import identifier is %s", importIdentifier))

result, err := r.client.GetObject(typeName, objID, layerID, layerType)
if err != nil {
resp.Diagnostics.AddError(
Expand All @@ -188,6 +195,7 @@ func (r *ObjectResource) Read(ctx context.Context, req resource.ReadRequest, res
return
}

tflog.Debug(ctx, fmt.Sprintf("api response is %s", string(result)))
// update the model with the new values
var parsedCurrentDataPayload map[string]any
var parsedResponse map[string]any
Expand All @@ -201,6 +209,7 @@ func (r *ObjectResource) Read(ctx context.Context, req resource.ReadRequest, res
return
}

tflog.Debug(ctx, fmt.Sprintf("parsed response into map is %v", parsedResponse))
if currentDataPayload != "" {
err = json.Unmarshal([]byte(currentDataPayload), &parsedCurrentDataPayload)
if err != nil {
Expand All @@ -212,7 +221,17 @@ func (r *ObjectResource) Read(ctx context.Context, req resource.ReadRequest, res
}
}

dataPayload := parsedResponse["data"].(map[string]any)
// if we can't fetch any data from the cloud return
var dataPayload map[string]any
var ok bool
if dataPayload, ok = parsedResponse["data"].(map[string]any); !ok {
resp.Diagnostics.AddError(
fmt.Sprintf("Unable to assert data map from current object of type %s with id %s", typeName, objID),
err.Error(),
)
return
}

if parsedCurrentDataPayload == nil {
// data was not provided in this case, maybe import usecase
// populate all the fields with what the observability api provided
Expand Down Expand Up @@ -255,9 +274,9 @@ func (r *ObjectResource) Read(ctx context.Context, req resource.ReadRequest, res
}

//nolint:gocritic // Terraform framework requires the method signature to be as is
func (r *ObjectResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
func (r *KnowledgeObjectResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
tflog.Debug(ctx, "Update method invoked")
var data ObjectResourceModel
var data KnowledgeObjectResourceModel

// Read Terraform plan data into the model
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
Expand Down Expand Up @@ -290,9 +309,9 @@ func (r *ObjectResource) Update(ctx context.Context, req resource.UpdateRequest,
}

//nolint:gocritic // Terraform framework requires the method signature to be as is
func (r *ObjectResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
func (r *KnowledgeObjectResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
tflog.Debug(ctx, "Delete method invoked")
var data ObjectResourceModel
var data KnowledgeObjectResourceModel

// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
Expand All @@ -317,6 +336,6 @@ func (r *ObjectResource) Delete(ctx context.Context, req resource.DeleteRequest,
}
}

func (r *ObjectResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
func (r *KnowledgeObjectResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("import_id"), req, resp)
}
Loading

0 comments on commit 7242ece

Please sign in to comment.