-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
New resource/datasource: SSL Policy #1247
Conversation
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 @nickjacques, this looks awesome!
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func dataSourceGoogleComputeSslPolicy() *schema.Resource { |
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.
We actually have some helpers that can simplify this code a fair bit- take a look at data_source_google_container_cluster.go
for an example. These'll help with code re-use, making it easier to keep the datasource/resource in sync in the future.
Schema: map[string]*schema.Schema{ | ||
|
||
"custom_features": &schema.Schema{ | ||
Type: schema.TypeList, |
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.
To answer your question- what you want here is a schema.TypeSet
. There are a whole bunch of examples of these around the codebase but let me know if you get stuck with how to use it!
ValidateFunc: validation.StringInSlice([]string{"TLS_1_0", "TLS_1_1", "TLS_1_2", "TLS_1_3"}, false), | ||
}, | ||
|
||
"name": &schema.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.
We're trying right now to put attributes in the order Required -> Optional -> Computed-only, if you don't mind reordering these
return fmt.Errorf("Error creating SSL Policy: %s", err) | ||
} | ||
|
||
err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutDelete).Minutes()), "Creating SSL Policy") |
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.
typo: schema.TimeoutCreate
return err | ||
} | ||
|
||
d.SetId(sslPolicy.Name) |
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.
I usually prefer to set the id between the Insert call and the Wait call- this way, if the terraform process stops for whatever reason, the Id is still set in state, meaning a subsequent refresh will get the created resource. Then if the wait operation stuff fails, you can do a d.SetId("")
before returning the error
"google_compute_ssl_policy.update", &sslPolicy), | ||
resource.TestCheckResourceAttr( | ||
"google_compute_ssl_policy.update", "profile", "MODERN"), | ||
//resource.TestCheckResourceAttr( |
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.
should this be uncommented?
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.
Ah, this was a result of the Fingerprint issue (the test was originally written to update two attributes). I'll make the update a full instead of partial and these tests should work properly with two attributes.
@@ -0,0 +1,50 @@ | |||
|
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.
nit: extra newline
|
||
```tf | ||
data "google_compute_ssl_policy" "my-ssl-policy" { | ||
name = "production-ssl-policy" |
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.
nit: extra spaces between name
and =
|
||
* `custom_features` - If the `profile` is `CUSTOM`, these are the custom encryption | ||
ciphers supported by the profile. If the `profile` is *not* `CUSTOM`, this | ||
attribute will be nil. |
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.
nit: since nil isn't really a terraform concept, let's say empty instead
"description": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, |
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.
this is surprising to me, can you confirm that the description can't be changed?
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.
I went off of the details provided in gcloud beta compute ssl-policies update
, which doesn't state that description is an updatable field, but I'll try against the API directly and see if it can be patched.
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.
I just tried updating two fields via API Explorer: minTlsVersion
and description
. The change was applied to minTlsVersion
but not description
, so I believe the ForceNew: true
is valid. If someone wants to change the resource description, a new resource must be created.
Okay, I think these latest commits resolve most of the comments - thanks for the tip on using Sets @danawillow, that worked perfectly! The only issue I'm encountering now is when updating a resource from: profile = "CUSTOM"
custom_features = ["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_3DES_EDE_CBC_SHA"] to something like: profile = "MODERN" In this scenario, I receive an error from the underlying API:
So it seems that I need to delete the |
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.
For the question about updating- the client library has a feature where it doesn't send fields that are set to the zero value to the API. You have to explicitly include them with ForceSendFields
or NullFields
. We use these a fair bit in the provider so you should be able to find an example. When you're testing it out, I also highly recommend running with debug logs on (TF_LOG=DEBUG) so you can see the requests/responses to/from the API. That'll help verify that the request you're sending is the one you expect. Hope that helps :)
addRequiredFieldsToSchema(dsSchema, "name") | ||
|
||
// Set 'Optional' schema elements | ||
addOptionalFieldsToSchema(dsSchema, "custom_features", "description", "min_tls_version", "profile", "project") |
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.
You probably just want "project" here- an optional field in a data source is one that you can choose to set in the data source itself, rather than all the fields that it might return. Setting something like custom_features wouldn't have any effect, because the data source is read-only.
Optional: true, | ||
Default: "TLS_1_0", | ||
// Although compute-gen.go says that TLS_1_3 is a valid value, the API currently (26 Mar 2018) | ||
// responds with an HTTP 200 but doesn't actually create/update the policy. |
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 that's distressing. Is there an issue in the public issue tracker that we could link to here?
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.
Not that I'm aware of, but I can file one if you'd like! Relevant lines are 21109-21118 in compute/v0.beta/compute-gen.go.
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.
If you don't mind, that would be great! That way if someone stumbles across this part of the code and sees a comment with a link to an issue that's been fixed, we'd be able to add TLS_1_3 real quick
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.
Ok, can do! Which product should I file it under? Cloud SDK?
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.
I'm not super familiar with how the products are laid out in components, but if there's one for compute admin api, or networking api, or something along those lines. I'm not going to block this PR on getting that link in there though. I'll finish up the review now :)
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.
No worries, I just added a link to the issue that Aaron created. (Thanks Aaron!)
return fmt.Errorf("Error updating SSL Policy: %s", err) | ||
} | ||
|
||
err = computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutCreate).Minutes()), "Updating SSL Policy") |
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.
This should probably be schema.TimeoutUpdate
return nil | ||
} | ||
|
||
func testAccCheckComputeSslPolicyCustomFeatures(sslPolicy *computeBeta.SslPolicy, n string) resource.TestCheckFunc { |
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.
You can actually get rid of this test function- the import check will verify this on its own (it'll call read and then try to populate state from it and compare it to the config, so if custom_features wasn't set upstream then the import would fail)
Gets an SSL Policy within GCE, for use with Target HTTPS and Target SSL Proxies. | ||
--- | ||
|
||
# google\_compute\_ssl\_policies |
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.
s/policies/policy
Manages an SSL Policy within GCE, for use with Target HTTPS and Target SSL Proxies. | ||
--- | ||
|
||
# google\_compute\_ssl\_policies |
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.
and here
Thanks @danawillow |
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.
Looks great! Just a few small nitpicks, if you don't mind :)
Fingerprint: d.Get("fingerprint").(string), | ||
} | ||
|
||
if v, ok := d.GetOk("profile"); 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.
nit: There isn't actually any difference between doing it this way and just setting it in the struct, since if the value is empty it'll be the empty string in the struct regardless.
resource.TestCheckResourceAttr( | ||
"google_compute_ssl_policy.update", "min_tls_version", "TLS_1_0"), | ||
), | ||
}, |
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.
let's also add the import test step here (and similarly after all test steps) juuuuuuuust in case
No worries at all! I've added |
👍 |
* Add SSL Policy to provider * Add resource for SSL Policy * Add SSL Policy data source * Add tests for SSL Policy resource * Add documentation for SSL Policy resource * Add SSL Policy datasource docs * Add test for SSL Policy datasource * Update SSL Policy datasource docs * Make full update for SSL Policy resource * SSL Policy resource test multi-attrib update * Clean up SSL Policy datasource * Set-ify custom_features in SSL Policy resource * Document description ForceNew rationale * Remove refs to TLS_1_3 * Update docs: plural -> singular * Remove extraneous attrs from datasource * Fix update logic for custom_features and add enabled_features * Update docs to include enabled_features * Add test for updating to/from custom_features * Add TLS 1.3 bug link * Add import between multi-step test configs * Move Profile and minTlsVersion back into sslPolicy struct
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks! |
Open questions:
custom_features
, TF will show a "perpetual diff" of the same contents in a different order. Since I'm a bit new to both developing TF resources and developing in Go, I'm seeking suggestions in how to best handle this.terraform plan
output, post-creation of resource:terraform apply
will fail with:This PR will resolve #1228 and paves the way for #1229 and #1230