Broken group update for artifactory_user resource
Closed this issue · 3 comments
Hi,
we have detected an issue that prevents user groups are updated. However, while reproducing/minimizing the issue we stumbled over some more -- related and unrelated -- issues which causes this ticket to likely become more elaborate. Still, our main intention is the ability to update groups of existing users.
Reproduction / Description
Short Version (not comprehensive)
Step 1: Create User
resource "artifactory_user" "test_user" {
name = "max_power"
email = "max.power@test.invalid"
admin = false
profile_updatable = true
disable_ui_access = false
internal_password_disabled = false
groups = []
}
Step 2: Add to group
resource "artifactory_user" "test_user" {
name = "max_power"
email = "max.power@test.invalid"
admin = false
profile_updatable = true
disable_ui_access = false
internal_password_disabled = false
groups = [artifactory_group.test_group.name]
}
resource "artifactory_group" "test_group" {
name = "temp-test"
description = "temp-test"
admin_privileges = false
lifecycle {
ignore_changes = [users_names]
}
}
Result
╷
│ Error: Unable to Update Resource
│
│ with artifactory_user.test_user,
│ on example.tf line 3, in resource "artifactory_user" "test_user":
│ 3: resource "artifactory_user" "test_user" {
│
│ An unexpected error occurred while updating the resource update request. Please report this issue to the provider developers.
│
│ Error: BAD_REQUEST - Cannot create a user without a password
The BAD_REQUEST
error stems from the access/api/v2/users/{name}
endpoint of the Artifactory API. As a result, we are not able to add the user to the group.
However, this is not the only error that prevents the desired result! Let us please give a more elaborate example:
Long Version (comprehensive)
Artifactory API Issue
When looking into the error above, we noticed the following behavior of the PACH access/api/v2/users/{name}
endpoint: When patching this endpoint with the field "internal_password_disabled": false
. This always raises the 400 error "Error: BAD_REQUEST - Cannot create a user without a password". According to the documentation, this should only be the case is this field is changed from "true" to "false", but apparently not. We opened a support ticket with Artifactory for this and tried to workaround this issue.
Step 1: Creater User
We want to create a user with "internal_password_disabled": true"
(since the provider always sends field on update). However, wenn trying
resource "artifactory_user" "test_user" {
name = "max_power"
email = "max.power@test.invalid"
admin = false
profile_updatable = true
disable_ui_access = false
internal_password_disabled = true
groups = []
}
Interestingly, this fails with
│
│ Error: BAD_REQUEST - Cannot set a password to a user for user with disabled internal password ('internal_password_disabled'=true)
╵
which is because the provider tries to set a dummy random password... so we return to first
setting
resource "artifactory_user" "test_user" {
name = "max_power"
email = "max.power@test.invalid"
admin = false
profile_updatable = true
disable_ui_access = false
internal_password_disabled = false
groups = []
}
and then update the user with
resource "artifactory_user" "test_user" {
name = "max_power"
email = "max.power@test.invalid"
admin = false
profile_updatable = true
disable_ui_access = false
internal_password_disabled = true
groups = []
}
Unfortunately, this does not work either since now we get an error
│
│ Error: BAD_REQUEST - Cant remove group that are not associated with the user
╵
This is now because the provider attempts to per default remove the "readers" group. However, this group has already been removed behind the scenes after creating the user. So we just add it:
resource "artifactory_user" "test_user" {
name = "max_power"
email = "max.power@test.invalid"
admin = false
profile_updatable = true
disable_ui_access = false
internal_password_disabled = true
groups = ["readers"]
}
This works. We have successfully created a user with internal_password_disabled = true
.
(Btw. even at this point has groups groups": []
when looking it up e.g. via API, but this is not important for us at this moment).
Step 2: Add it to a group
We now add the user to a group
resource "artifactory_user" "test_user" {
name = "max_power"
email = "max.power@test.invalid"
admin = false
profile_updatable = true
disable_ui_access = false
internal_password_disabled = true
groups = ["readers", artifactory_group.test_group.name]
}
resource "artifactory_group" "test_group" {
name = "temp-test"
description = "temp-test"
admin_privileges = false
lifecycle {
ignore_changes = [users_names]
}
}
The terraform result looks fine, too. Even more, the state is stable (further planning does not show any changes)
However requesting now GET <ARTIFACTORY_URL>/access/api/v2/users/max_power
gives us:
{
"username": "max_power",
"email": "max.power@test.invalid",
"admin": false,
"effective_admin": false,
"profile_updatable": true,
"disable_ui_access": false,
"internal_password_disabled": true,
"last_logged_in": "1970-01-01T00:00:00.000Z",
"realm": "internal",
"groups": [],
"status": "enabled"
}
Expected behavior
The final "get" should give
{
"username": "max_power",
"email": "max.power@test.invalid",
"admin": false,
"effective_admin": false,
"profile_updatable": true,
"disable_ui_access": false,
"internal_password_disabled": true,
"last_logged_in": "1970-01-01T00:00:00.000Z",
"realm": "internal",
"groups": ["readers", "temp-test"],
"status": "enabled"
}
Version
We are using provider jfrog/artifactory 10.3.3 with opentofu 1.6.2
Additional context
From our understanding, the PATCH <ARTIFACTORY_URL>/access/api/v2/users/{name}
does not support changing user groups. From very briefly looking into the go implementation, we conclude the update function is possibly missing a dedicated step to update the groups again (via a call to UserGroupEndpointPath
in additon to the removeReadersGroup
call).
@fabiankle The first issue with user can't be created with a password when internal_password_disabled
set to true
is a bug in the provider. It should take into account internal_password_disabled
when attempting to create a random password if password
attribute is not set.
@fabiankle As for the groups
attribute behavior, the cause is from this issue. The challenge here is that all groups that have autoJoin
set to true
will appear in the user.groups
field after creation. This cause state drift unless those groups are specified in the configuration.
One solution is to compare the groups
API field against the groups
TF attribute and add/remove any groups as necessary (not just special group like 'readers').
--
As for your long scenario, I was not able to replicate the first issue in there. After I unset 'auto join' for the 'readers' group, I was able to create a new user (via API) with empty groups
field. The API response also contains an empty groups
field, thus should not cause a TF state drift (thus requiring add readers
to groups
attribute list). I'll try to replicate this in TF today.
Hi @alexhung ,
first of all thanks for the very quick reply!
In the end, the important thing for us would be to be able to adapt a user's group after it has been created (as mentioned we did open a ticket with Jfrog directly concerning internal_password_disabled
issue, we're just convinced this alone will not fix our issue, hence the long version)
If it is any help for you, I could also provide you with the full logs (plan & apply) of the steps, please just let me know!
Best,
FAbian