OpsLevel / terraform-provider-opslevel

Terraform provider for OpsLevel.com
https://registry.terraform.io/providers/OpsLevel/opslevel/latest/docs
MIT License
8 stars 5 forks source link

convert Predicate types to ObjectValue in opslevel_check_tool_usage #367

Closed davidbloss closed 1 month ago

davidbloss commented 1 month ago

Issues

Fix this:

│ Error: Value Conversion Error
│ 
│ An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:
│ 
│ Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.
│ 
│ Path: tool_url_predicate
│ Target Type: opslevel.PredicateModel
│ Suggested `types` Type: basetypes.ObjectValue
│ Suggested Pointer Type: *opslevel.PredicateModel

Changelog

PredicateModel has useful functions that remain. The schema now accepts ObjectValues instead and Terraform understands how to interpret these better than a custom struct with tfsdk tags.

Tophatting

With this Terraform config (note *_predicate blocks):

resource "opslevel_check_tool_usage" "example" {
  name          = "foo the barz"
  enabled       = true
  category      = "Z2lkOi8vb3BzbGV2ZWwvQ2F0ZWdvcnkvNjk3Nw"
  level         = "Z2lkOi8vb3BzbGV2ZWwvTGV2ZWwvMzcwOA"
  owner         = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xNzQzNA"
  filter        = "Z2lkOi8vb3BzbGV2ZWwvRmlsdGVyLzM1Njk"
  tool_category = "metrics"
  environment_predicate = {
    type  = "ends_with"
    value = "the sea"
  }
  tool_name_predicate = {
    type  = "exists"
    value = ""
  }
  tool_url_predicate = {
    type  = "starts_with"
    value = "https"
  }
  notes = "Optional additional info on why this check is run or how to fix it"
}

Create opslevel_check_tool_usage with predicates. terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # opslevel_check_tool_usage.example will be created
  + resource "opslevel_check_tool_usage" "example" {
      + category              = "Z2lkOi8vb3BzbGV2ZWwvQ2F0ZWdvcnkvNjk3Nw"
      + description           = (known after apply)
      + enabled               = true
      + environment_predicate = {
          + type  = "ends_with"
          + value = "the sea"
        }
      + filter                = "Z2lkOi8vb3BzbGV2ZWwvRmlsdGVyLzM1Njk"
      + id                    = (known after apply)
      + level                 = "Z2lkOi8vb3BzbGV2ZWwvTGV2ZWwvMzcwOA"
      + name                  = "foo the barz"
      + notes                 = "Optional additional info on why this check is run or how to fix it"
      + owner                 = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xNzQzNA"
      + tool_category         = "metrics"
      + tool_name_predicate   = {
          + type  = "exists"
          + value = ""
        }
      + tool_url_predicate    = {
          + type  = "starts_with"
          + value = "https"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
opslevel_check_tool_usage.example: Creating...
opslevel_check_tool_usage.example: Creation complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTE]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Destroy opslevel_check_tool_usage with predicates. terraform destroy

opslevel_check_tool_usage.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTE]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # opslevel_check_tool_usage.example will be destroyed
  - resource "opslevel_check_tool_usage" "example" {
      - category              = "Z2lkOi8vb3BzbGV2ZWwvQ2F0ZWdvcnkvNjk3Nw" -> null
      - description           = "The service has a metrics tool whose name exists in an environment which ends with 'the sea' with a url which starts with 'https'." -> null
      - enabled               = true -> null
      - environment_predicate = {
          - type  = "ends_with" -> null
          - value = "the sea" -> null
        } -> null
      - filter                = "Z2lkOi8vb3BzbGV2ZWwvRmlsdGVyLzM1Njk" -> null
      - id                    = "Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTE" -> null
      - level                 = "Z2lkOi8vb3BzbGV2ZWwvTGV2ZWwvMzcwOA" -> null
      - name                  = "foo the barz" -> null
      - notes                 = "Optional additional info on why this check is run or how to fix it" -> null
      - owner                 = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xNzQzNA" -> null
      - tool_category         = "metrics" -> null
      - tool_name_predicate   = {
          - type  = "exists" -> null
          - value = "" -> null
        } -> null
      - tool_url_predicate    = {
          - type  = "starts_with" -> null
          - value = "https" -> null
        } -> null
    }

Plan: 0 to add, 0 to change, 1 to destroy.
opslevel_check_tool_usage.example: Destroying... [id=Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTE]
opslevel_check_tool_usage.example: Destruction complete after 0s

Destroy complete! Resources: 1 destroyed.

Update Terraform config. *_predicate blocks commented out:

resource "opslevel_check_tool_usage" "example" {
  name          = "foo the barz"
  enabled       = true
  category      = "Z2lkOi8vb3BzbGV2ZWwvQ2F0ZWdvcnkvNjk3Nw"
  level         = "Z2lkOi8vb3BzbGV2ZWwvTGV2ZWwvMzcwOA"
  owner         = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xNzQzNA"
  filter        = "Z2lkOi8vb3BzbGV2ZWwvRmlsdGVyLzM1Njk"
  tool_category = "metrics"
  # environment_predicate = {
  #   type  = "ends_with"
  #   value = "the sea"
  # }
  # tool_name_predicate = {
  #   type  = "exists"
  #   value = ""
  # }
  # tool_url_predicate = {
  #   type  = "starts_with"
  #   value = "https"
  # }
  notes = "Optional additional info on why this check is run or how to fix it"
}

Create opslevel_check_tool_usage with no predicates. terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # opslevel_check_tool_usage.example will be created
  + resource "opslevel_check_tool_usage" "example" {
      + category      = "Z2lkOi8vb3BzbGV2ZWwvQ2F0ZWdvcnkvNjk3Nw"
      + description   = (known after apply)
      + enabled       = true
      + filter        = "Z2lkOi8vb3BzbGV2ZWwvRmlsdGVyLzM1Njk"
      + id            = (known after apply)
      + level         = "Z2lkOi8vb3BzbGV2ZWwvTGV2ZWwvMzcwOA"
      + name          = "foo the barz"
      + notes         = "Optional additional info on why this check is run or how to fix it"
      + owner         = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xNzQzNA"
      + tool_category = "metrics"
    }

Plan: 1 to add, 0 to change, 0 to destroy.
opslevel_check_tool_usage.example: Creating...
opslevel_check_tool_usage.example: Creation complete after 1s [id=Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTI]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Update Terraform config. Add *_predicate blocks:

resource "opslevel_check_tool_usage" "example" {
  name          = "foo the barz"
  enabled       = true
  category      = "Z2lkOi8vb3BzbGV2ZWwvQ2F0ZWdvcnkvNjk3Nw"
  level         = "Z2lkOi8vb3BzbGV2ZWwvTGV2ZWwvMzcwOA"
  owner         = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xNzQzNA"
  filter        = "Z2lkOi8vb3BzbGV2ZWwvRmlsdGVyLzM1Njk"
  tool_category = "metrics"
  environment_predicate = {
    type  = "ends_with"
    value = "the sea"
  }
  tool_name_predicate = {
    type  = "exists"
    value = ""
  }
  tool_url_predicate = {
    type  = "starts_with"
    value = "https"
  }
  notes = "Optional additional info on why this check is run or how to fix it"
}

Update opslevel_check_tool_usage, add predicates. terraform apply:

opslevel_check_tool_usage.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTI]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # opslevel_check_tool_usage.example will be updated in-place
  ~ resource "opslevel_check_tool_usage" "example" {
      ~ description           = "The service has a metrics tool." -> (known after apply)
      + environment_predicate = {
          + type  = "ends_with"
          + value = "the sea"
        }
        id                    = "Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTI"
        name                  = "foo the barz"
      + tool_name_predicate   = {
          + type  = "exists"
          + value = ""
        }
      + tool_url_predicate    = {
          + type  = "starts_with"
          + value = "https"
        }
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
opslevel_check_tool_usage.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTI]
opslevel_check_tool_usage.example: Modifications complete after 0s [id=Z2lkOi8vb3BzbGV2ZWwvQ2hlY2tzOjpUb29sVXNhZ2UvMjYwNTI]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.