cli icon indicating copy to clipboard operation
cli copied to clipboard

The deprecated "contains" keyword works but the recommended "has" keyword results in an error.

Open supersmo opened this issue 4 years ago • 5 comments

Description : The deprecated "contains" keyword works but the recommended "has" keyword results in an error

Scenario with "contains" keyword:

Feature: Location restriction

Scenario: Location control on all resources that have location defined
    Given I have a resource defined that supports location
    When it contains location
    Then its value must match the "^eur(4|3)$|^europe-(north1|west(1|3|4))$" regex

Result with "contains" keyword:

PS C:\ws\github.com\terraform-compliance-terraform-13-error> terraform-compliance -f ./terrafo
rm-compliance-rules -p planfile
terraform-compliance v1.3.4 initiated

. Converting terraform plan file.
🚩 Features     : C:\ws\github.com\terraform-compliance-terraform-13-error\terraform-compliance-rules/
🚩 Plan File    : C:\ws\github.com\terraform-compliance-terraform-13-error\planfile.json

🚩 Running tests. 🎉

Feature: Location restriction  # C:\ws\github.com\terraform-compliance-terraform-13-error\terraform-compliance-rules/locationcheck.feature

    Scenario: Location control on all resources that have location defined
        Given I have a resource defined that supports location
        ❗ WARNING: "When it contains location" step functionality will be changed on future versions and the functionality will be same as "When it has location" step. Please use the latter.
        When it contains location
        Then its value must match the "^eur(4|3)$|^europe-(north1|west(1|3|4))$" regex

1 features (1 passed)
1 scenarios (1 passed)
3 steps (3 passed)
Run 1601280291 finished within a moment

Scenario with "has" keyword:

Feature: Location restriction

Scenario: Location control on all resources that have location defined
    Given I have a resource defined that supports location
    When it has location
    Then its value must match the "^eur(4|3)$|^europe-(north1|west(1|3|4))$" regex

Result with "has" keyword:

PS C:\ws\github.com\terraform-compliance-terraform-13-error> terraform-compliance -f ./terrafo
rm-compliance-rules -p planfile
terraform-compliance v1.3.4 initiated

. Converting terraform plan file.
🚩 Features     : C:\ws\github.com\terraform-compliance-terraform-13-error\terraform-compliance-rules/
🚩 Plan File    : C:\ws\github.com\terraform-compliance-terraform-13-error\planfile.json

🚩 Running tests. 🎉

Feature: Location restriction  # C:\ws\github.com\terraform-compliance-terraform-13-error\terraform-compliance-rules/locationcheck.feature

    Scenario: Location control on all resources that have location defined
        Given I have a resource defined that supports location
        When it has location
                Failure: location property in google_storage_bucket.example-bucket resource does not match with ^eur(4|3)$|^europe-(north1|west(1|3|4))$ case insensitive regex. It is set to None.
                Failure: location property in google_storage_bucket.example-bucket resource does not match with ^eur(4|3)$|^europe-(north1|west(1|3|4))$ case insensitive regex. It is set to False.
                Failure: location property in google_storage_bucket.example-bucket resource does not match with ^eur(4|3)$|^europe-(north1|west(1|3|4))$ case insensitive regex. It is set to None.
                Failure: location property in google_storage_bucket.example-bucket resource does not match with ^eur(4|3)$|^europe-(north1|west(1|3|4))$ case insensitive regex. It is set to *****.
                Failure: location property in google_storage_bucket.example-bucket resource does not match with ^eur(4|3)$|^europe-(north1|west(1|3|4))$ case insensitive regex. It is set to None.
                Failure: location property in google_storage_bucket.example-bucket resource does not match with ^eur(4|3)$|^europe-(north1|west(1|3|4))$ case insensitive regex. It is set to STANDARD.
                Failure: location property in google_storage_bucket.example-bucket resource does not match with ^eur(4|3)$|^europe-(north1|west(1|3|4))$ case insensitive regex. It is set to True.
        Then its value must match the "^eur(4|3)$|^europe-(north1|west(1|3|4))$" regex
          Failure:

1 features (0 passed, 1 failed)
1 scenarios (0 passed, 1 failed)
3 steps (2 passed, 1 failed)
Run 1601280809 finished within a moment

As seen above all values of the resource are evaluated and not just the location.

To Reproduce

  1. Clone https://github.com/supersmo/terraform-compliance-1.3.4-has-keyword-error
  2. cd into the repo directory
  3. run terraform-compliance -f ./terraform-compliance-rules -p planfile

Expected behavior : The scenario should run without errors and "has" should be have like "contains".

Tested versions :

  • terraform-compliance version 1.3.4
  • terraform version 0.13.3
  • python runtime version Python 3.8.5

supersmo avatar Sep 28 '20 09:09 supersmo

Double +1 on this, the warnings create lots of extra noise on the Scenario Outline and as stated above, render them useless when changing to the new syntax

mdesmarest avatar Sep 29 '20 16:09 mdesmarest

Any movement on this? its making feature writing a bit challenging. @eerkunt

mdesmarest avatar Oct 12 '20 14:10 mdesmarest

Same issue over here.

We look for a tag of Version: X but when we use the has keyword it finds other elements containing the key Version;

ie

		Failure: Version property in aws_iam_role.newrelic_aws_integration resource does not match with ^(\d+\.\d+\.\d+|feature/.*)$ case insensitive regex. It is set to 2012-10-17.
        | Version     | ^(\d+\.\d+\.\d+|feature/.*)$                                                                                                            |
          Failure: 

eperdeme avatar Nov 03 '20 10:11 eperdeme

I've seen this issue as well. It appears to be interrogating the top level resource in the 'Then its value' evaluation. I've had success working through it by switching the when/then to a when/then/and. So for the scenario documented above, switching it to:

Scenario: Location control on all resources that have location defined
    Given I have a resource defined that supports location
    When it has location
    Then it must contain location
    And its value must match the "^eur(4|3)$|^europe-(north1|west(1|3|4))$" regex

It seems that the 'Then' pushes the 'location' into the final evaluation.

jrsherry avatar Jan 25 '21 13:01 jrsherry

Thanks for posting a workaround! I can confirm that it works. Will switch to that syntax. Still I think this is a bug that should be fixed.

supersmo avatar Feb 18 '21 10:02 supersmo