Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(project_user): Recreate project_user if ignore_missing_user #177

Merged
merged 1 commit into from
Nov 19, 2024

Conversation

Danielku15
Copy link
Contributor

@Danielku15 Danielku15 commented Nov 18, 2024

Fixes #175

I manually tested the change to work as expected using a local provider build. I also extended the integration test to check the expected state and actions. Due to a lack of test-env I cannot check if the tests are really green like this. I might need some assistence there.

},
},
// expect user to be added to state
Check: resource.ComposeTestCheckFunc(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the error from the acceptance tests:

=== RUN   TestAccProjectMember_missing_user_ignored
    resource_project_user_test.go:394: Step 1/4 error: After applying this test step, the refresh plan was not empty.
        stdout


        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:

          # project_user.not_existingsolpd will be created
          + resource "project_user" "not_existingsolpd" {
              + id                  = (known after apply)
              + ignore_missing_user = true
              + name                = "not_existingsolpd"
              + project_key         = "czmmvqeaxp"
              + roles               = [
                  + "Developer",
                  + "Project Admin",
                ]
            }

        Plan: 1 to add, 0 to change, 0 to destroy.
--- FAIL: TestAccProjectMember_missing_user_ignored (2.94s)
FAIL
FAIL	github.com/jfrog/terraform-provider-project/pkg/project/resource	4.160s
FAIL

I think you'll need:

  1. Add ExpectNonEmtpyPlan: true
  2. Remove Check: ... since there'd be no state being saved by the resource.

Copy link
Contributor Author

@Danielku15 Danielku15 Nov 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Add ExpectNonEmtpyPlan: true

Yes, this looks promising according to: https://github.com/hashicorp/terraform-plugin-testing/blob/4a889266a95c9a38734a7c9f6e079b641a8fae53/helper/resource/testing_new_config.go#L358-L376

I updated the PR with annotations on the first 3 steps where the plan should not be empty.

  1. Remove Check: ... since there'd be no state being saved by the resource.

TF will still write the project_user to state in this variant of the fix. My initial attempt to not write a state entry failed. TF will report an error if a TF provider does not create a state entry for a resource. So its either "fail" or "create state entry".

The key change in this PR is that on a read we remove the item from the state if it is missing (causing a create to be detected on plan). Hence the assertions that the state has values as I've seen it on manual tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the test Steps that pass for me:

Steps: []resource.TestStep{
	// attempt create, will not work
	{
		Config: config,
		ConfigPlanChecks: resource.ConfigPlanChecks{
			PostApplyPostRefresh: []plancheck.PlanCheck{
				// expect create of project user
				plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
			},
		},
		ExpectNonEmptyPlan: true,
		// expect user to be added to state
		Check: resource.ComposeTestCheckFunc(
			resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
			resource.TestCheckResourceAttr(resourceName, "name", username),
			resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
			resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
			resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
			resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
		)},
	// re-attempt create, will still not work
	{
		Config: config,
		ConfigPlanChecks: resource.ConfigPlanChecks{
			PostApplyPostRefresh: []plancheck.PlanCheck{
				// again expect create of project user (refresh will mark project user as missing)
				plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
			},
		},
		ExpectNonEmptyPlan: true,
		// expect user to be in the state
		Check: resource.ComposeTestCheckFunc(
			resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
			resource.TestCheckResourceAttr(resourceName, "name", username),
			resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
			resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
			resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
			resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
		)},
	// re-attempt create with user being added, will work
	{
		Config: configUpdated,
		ConfigPlanChecks: resource.ConfigPlanChecks{
			PreApply: []plancheck.PlanCheck{
				// again expect create of project user (refresh will mark project user as missing)
				plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
			},
			PostApplyPostRefresh: []plancheck.PlanCheck{
				// again expect create of project user (refresh will mark project user as missing)
				plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
			},
		},
		// expect user to be in the state
		Check: resource.ComposeTestCheckFunc(
			resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
			resource.TestCheckResourceAttr(resourceName, "name", username),
			resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
			resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
			resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
			resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
		)},
	// now user is there, no action should be performed
	{
		Config: configUpdated,
		ConfigPlanChecks: resource.ConfigPlanChecks{
			PostApplyPostRefresh: []plancheck.PlanCheck{
				// again expect create of project user (refresh will mark project user as missing)
				plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
			},
		},
		// expect user to be in the state
		Check: resource.ComposeTestCheckFunc(
			resource.TestCheckResourceAttr(resourceName, "project_key", fmt.Sprintf("%s", params["project_key"])),
			resource.TestCheckResourceAttr(resourceName, "name", username),
			resource.TestCheckResourceAttr(resourceName, "ignore_missing_user", "true"),
			resource.TestCheckResourceAttr(resourceName, "roles.#", "2"),
			resource.TestCheckResourceAttr(resourceName, "roles.0", "Developer"),
			resource.TestCheckResourceAttr(resourceName, "roles.1", "Project Admin"),
		)},
	},
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also need to add this to TestCase for step 3 to work:

ExternalProviders: map[string]resource.ExternalProvider{
	"artifactory": {
		Source: "jfrog/artifactory",
	},
},

Copy link
Contributor Author

@Danielku15 Danielku15 Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexhung Highly appreciate your help here due to my lack of a test environment. I updated the PR with your proposed changes. The changes make sense and still fit my expectations on how things should work. I'm still fairly new to developing TF providers, a lot of unknowns in the testing framework 😁

@Danielku15 Danielku15 force-pushed the feature/fix-user-recreation branch from 8578120 to 509221c Compare November 18, 2024 18:21
@Danielku15 Danielku15 requested a review from alexhung November 18, 2024 18:22
@Danielku15 Danielku15 force-pushed the feature/fix-user-recreation branch from 509221c to b15c57d Compare November 19, 2024 07:54
Copy link
Member

@alexhung alexhung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :shipit:

@alexhung alexhung merged commit 07d0412 into jfrog:master Nov 19, 2024
2 of 4 checks passed
@alexhung alexhung added the bug Something isn't working label Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

project_user not properly created in combination with ignore_missing_user
2 participants