-
Notifications
You must be signed in to change notification settings - Fork 669
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
Deprecate Whitelist for IBM-cloud-databases. Introduce allowlisting #3852
Conversation
whitelist, err := icdClient.Whitelists().GetWhitelist(icdId) | ||
if err != nil { | ||
return fmt.Errorf("[ERROR] Error getting database whitelist: %s", err) | ||
if _, ok := d.GetOk("whitelist"); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whitelist and allowlist are computed variables you can't do d.GetOk...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use cloud v5 API and flatten the result back to both whitelist and allowlist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hkantare unfortunately we can't. Whitelist does not exist in v5 and was replaced by allowlist. So whitelist is using v4 while allowlist uses v5.
v5 API: https://cloud.ibm.com/apidocs/cloud-databases-api/cloud-databases-api-v5#getallowlist
v4 API: https://cloud.ibm.com/apidocs/cloud-databases-api/cloud-databases-api-v4#getwhitelist-permissions
Thank you for catching the previous mistake though! I really appreciate it!
Deprecated: "Whitelist is deprecated please use allowlist", | ||
ConflictsWith: []string{"allowlist"}, | ||
}, | ||
"allowlist": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we set the v5 API response of allowlist to whitelist (because the schema looks same for both) it just flatten and setting the same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @hkantare!
They're two different apis endpoints, and despite them being very similar, I think it's safer to keep them separate. Whitelist is depreciated and will be removed soon as well. Hence, I think a separation of concerns is better. Here are the api docs for both. #3852 (comment)
Thanks!
Omar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes ...v4/v5 API are two different endpoint with same model structure and functionality ...cant we just handle in the backend (i mean resource/datasource) to migrate to V5 AP's without any change to schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hkantare so the responses are the same yes :D But the supporting functionality is not. Meaning, the autogenerated allowlist functions utilize allowlist structs the use pointers. For example, https://github.com/IBM/cloud-databases-go-sdk/blob/de91b81e136fd4c53c0000e87932aaf150658a33/clouddatabasesv5/cloud_databases_v5.go#L1848
In contrast the whitelist functions utilizes a whitelist struct that does not use pointers. An example of the functions that consume structs that are shaped differently can be found here: https://github.com/IBM-Cloud/bluemix-go/blob/d538cb4fd9bece50f7b012496df63b3f62d58662/api/icd/icdv4/whitelist.go#L38
So despite achieving the same result, the code is structured very differently and the structs that allowlist relies on are different than whitelist. For example, AllowlistEntry
is written as follows: https://github.com/IBM/cloud-databases-go-sdk/blob/de91b81e136fd4c53c0000e87932aaf150658a33/clouddatabasesv5/cloud_databases_v5.go#L2046
While WhitelistEntry
is written as follows https://github.com/IBM-Cloud/bluemix-go/blob/d538cb4fd9bece50f7b012496df63b3f62d58662/api/icd/icdv4/whitelist.go#L13
My concern of just setting the v5 response of allowlist to whitelist is we'll have to do lots of downstream changes that will break things or cause unexpected bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I also tested the instances using import and it works :)
whitelist, err := icdClient.Whitelists().GetWhitelist(icdId) | ||
if err != nil { | ||
return diag.FromErr(fmt.Errorf("[ERROR] Error getting database whitelist: %s", err)) | ||
if _, ok := d.GetOk("whitelist"); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Resource Read also don't use d.Get operations because the import functionality doesn't work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @hkantare!
Thanks for taking a look at the PR. I really appreciate it! After spending a few days trying to incorporate this requested change, I am not convinced that it is a good idea. Removing the operation actually causes bugs as seen below:
test_working_directory=/var/folders/zl/1pk63bj95xx56m3vvm0yn35m0000gn/T/plugintest824757667
error=
| After applying this test step and performing a `terraform refresh`, the plan was not empty.
| stdout
|
|
| 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:
|
| # ibm_database.tf-edb-58 will be updated in-place
| ~ resource "ibm_database" "tf-edb-58" {
| id = "crn:v1:bluemix:public:databases-for-enterprisedb:eu-gb:a/40ddc34a953a8c02f10987b59085b60e:c1ff0800-8682-4b6b-a8b7-5fa8df912a31::"
| name = "tf-edb-58"
| tags = [
| "one:two",
| ]
| # (25 unchanged attributes hidden)
|
|
|
|
|
| - whitelist {
| - address = "172.168.1.2/32" -> null
| - description = "desc1" -> null
| }
| # (4 unchanged blocks hidden)
| }
|
| Plan: 0 to add, 1 to change, 0 to destroy.
resource_ibm_database_edb_test.go:25: Step 1/4 error: After applying this test step and performing a `terraform refresh`, the plan was not empty.
stdout
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:
# ibm_database.tf-edb-58 will be updated in-place
~ resource "ibm_database" "tf-edb-58" {
id = "crn:v1:bluemix:public:databases-for-enterprisedb:eu-gb:a/40ddc34a953a8c02f10987b59085b60e:c1ff0800-8682-4b6b-a8b7-5fa8df912a31::"
name = "tf-edb-58"
tags = [
"one:two",
]
# (25 unchanged attributes hidden)
- whitelist {
- address = "172.168.1.2/32" -> null
- description = "desc1" -> null
}
# (4 unchanged blocks hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
Here's my explanation as to why d.GetOK
is actually vital:
getOK
does work in resource read (I've confirmed this). In general we use many operations associated with the resourceDataStructure throughout the function and this isn't any different really.- By taking it away, we end up setting whitelist to a value. The reason begin is the api commands for allowlist and whitelist update the same source. We do not want to set our whitelist to anything if allowlist is used, and vice versa.
- By not doing the above we end up setting whitelist to some value. This value then gets updated to null down the line. This is bad and can cause unintended bugs like overwriting data.
- Also note, whitelist and allowlist are special cases where both apis do the same exact thing. This is highly unusual, but it is what it is.
Hence, the best was to approach this is the original way which is check if allowlist or whitelist is used. Then proceed to do the api calls depending on which one is used. Both can never be set at the same time due to the conflict code, and we’ve established that d.getOK does work perfectly fine.
Thanks!
Omar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for explanation
getOK does work in resource read but it fails during the import scenario. Let say you have created a database outside Terraform and want to import and manage in future using Terraform. We need to import the resource. (https://learn.hashicorp.com/tutorials/terraform/state-import?in=terraform/state&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS)
For import we first create a empty resource block
resource "ibm_database" "mydb" {
}
Run terraform import ibm_database.mydb
Import also calls the same resource read since the block is empty d.GetOk fails for both whitelist and allowlist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hkantare thank you very very much for the explanation :D I've gone ahead and update the code so that if whitelist isn't there we always use allowlist. I follow the terraform docs here: https://www.terraform.io/plugin/sdkv2/best-practices/deprecations#renaming-an-optional-attribute
So if d.getOK("whitelist")
fails we'll always use allowlist. lmk what you think :D
…der-ibm into icd-allowlist
e07c2f7
to
17b24e9
Compare
@omaraibrahim Can you add a migration testcase from whitelist to allowlist |
@hkantare I've gone ahead and added migration tests. I've also modified the code to address some concerns and ensure a seemless migration to Migration tests can be found here: terraform-provider-ibm/ibm/service/database/resource_ibm_database_postgresql_test.go Line 105 in 9845af3
|
…3852) * works with local vendor changes. * working using cloud databases v5 now * updated deprecation message * data_source_ibm_database and some tests * modified the rest of the resource tests * fixed calling d.getOK for computed variable * potential import issue fix * added migration test * fixed migration bug * fixed allowlist removal bug * setting import state verify to false due to terraform bug * removed extra logs * updated docs
In the api version 5 whitelist was deprecated and allowlist was introduced. In our strive for feature parity, in the following PR I deprecated whitelist and introduced allowlist.
This involved:
Community Note
Relates OR Closes #0000
Output from acceptance testing: