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

Add support for Cloud Asset feeds #3750

Merged
merged 17 commits into from
Jul 21, 2020

Conversation

apsureda
Copy link
Contributor

Added resources for the Cloud Asset Inventory feeds. The feeds requires the billing project to be passed on via the X-Goog-User-Project HTTP header. In order to accomplish this without modifying the current transport logic, I have added a pre_create custom code hook right before the sendRequestWithTimeout function. It would be preferable to provide a proper option to do this without abusing the UserProjectOverride field.

This API is weird in the sense that the feed payload needs to be sent under a feed attribute, but in the HTTP response the payload is directly in the body. I solved this by moving the feed under a feed attribute in the pre_commit and pre_update hooks.

Release Note Template for Downstream PRs (will be copied)

`google_cloud_asset_organization_feed`
`google_cloud_asset_folder_feed`
`google_cloud_asset_project_feed`

@modular-magician
Copy link
Collaborator

Hello! I am a robot who works on Magic Modules PRs.

I have detected that you are a community contributor, so your PR will be assigned to someone with a commit-bit on this repo for initial review.

Thanks for your contribution! A human will be with you soon.

@megan07, please review this PR or find an appropriate assignee.

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are.

Diff report:

Terraform GA: Diff ( 154 files changed, 2829 insertions(+), 2 deletions(-))
Terraform Beta: Diff ( 184 files changed, 2859 insertions(+), 2 deletions(-))
TF Conversion: Diff ( 4 files changed, 369 insertions(+))

@apsureda apsureda changed the title Clooud asset feeds Add support for Cloud Asset feeds Jul 16, 2020
@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are.

Diff report:

Terraform GA: Diff ( 15 files changed, 2684 insertions(+), 2 deletions(-))
Terraform Beta: Diff ( 15 files changed, 2684 insertions(+), 2 deletions(-))
TF Conversion: Diff ( 4 files changed, 369 insertions(+))

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are.

Diff report:

Terraform GA: Diff ( 15 files changed, 2684 insertions(+), 2 deletions(-))
Terraform Beta: Diff ( 15 files changed, 2684 insertions(+), 2 deletions(-))
TF Conversion: Diff ( 4 files changed, 369 insertions(+))

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are.

Diff report:

Terraform GA: Diff ( 15 files changed, 2696 insertions(+), 2 deletions(-))
Terraform Beta: Diff ( 15 files changed, 2696 insertions(+), 2 deletions(-))
TF Conversion: Diff ( 4 files changed, 369 insertions(+))

Copy link
Contributor

@megan07 megan07 left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution! It looks great! Just a few comments - I had to learn about the resources while I looked through it, so please let me know if you think I misunderstood any of it.

@@ -0,0 +1,252 @@
# Copyright 2019 Google Inc.
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you mind changing the copyright to 2020, please? This is applicable to the other files as well. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

products/cloudasset/api.yaml Show resolved Hide resolved
the feed. For example: "compute.googleapis.com/Disk"
See https://cloud.google.com/asset-inventory/docs/supported-asset-types for a list of all
supported asset types.
- !ruby/object:Api::Type::String
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be Type::Enum and we can list the values here. This is applicable for all the different types of feeds.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah! Good to know. I did not know how to indicate that. The contentType is indeed an Enum. I'll change that.

Destination on Cloud Pubsub topic.
- !ruby/object:Api::Resource
name: FolderFeed
base_url: "{{folder}}/feeds"
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want the prefix folders in the base_url and create_url? I assume it's not here because the name returned from the google_folder resource/data source already has the prefix, but as I'm looking over it, I wonder if maybe we want to add a computed attribute, folder_id on the folder, that would be just the folder id rather than the full name. It should be a quick add. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are right. I did not like it either. I'll try to change this, and come back if I have any question on how to do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't like this either. I have added the folder_id computed attribute as suggested.

'https://cloud.google.com/asset-inventory/docs'
api: 'https://cloud.google.com/asset-inventory/docs/reference/rest/'
properties:
- !ruby/object:Api::Type::String
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we might want to put this under a parameters block rather than properties

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure I understand the difference between the two but, if it seems right, Why not?

Copy link
Contributor

Choose a reason for hiding this comment

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

My understanding is there's not really a technical difference between the two (the technical importance is url_param_only), but more of an organizational difference. Thanks!

url_param_only: true
description: |
The organization this feed should be created in.
- !ruby/object:Api::Type::String
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this necessary for organization feeds? I think this would be handled with supports_indirect_user_project_override

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Just like in the case of the FolderFeed, I am using this flag only to get the "project" var declared before the sendRequestWithTimeout function is called. Not the way I'd like to do it, but currently the only way to set the billing project header.

'https://cloud.google.com/asset-inventory/docs'
api: 'https://cloud.google.com/asset-inventory/docs/reference/rest/'
properties:
- !ruby/object:Api::Type::String
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we want to put this under a parameters block as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As mentioned earlier, seems right.

@@ -0,0 +1,16 @@
// The feed object must be under the "feed" attribute on the request.
Copy link
Contributor

Choose a reason for hiding this comment

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

Would we be able to achieve this with an encoder rather than requiring a pre-create and pre-update. It looks as though the functionality is a little different among create, update and delete. I'm not sure if this is something we could capture in an encoder or not, but wanted to suggest it if it's possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't know about encoders! This is definitely better suited for an encoder. At least, the part where I rearrange the obj structure. The billing project part, however, still requires a custom code hook.

api: 'https://cloud.google.com/asset-inventory/docs/reference/rest/'
properties:
- !ruby/object:Api::Type::String
name: billing_project
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you mind explaining what billing_project is used for here? I think if you're looking to override the project, you should be able to just call it project. Is that the intent? It also would not need to be url_param_only.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See an explanation for this in this comment: #3750 (comment)

--- !ruby/object:Provider::Terraform::Config
overrides: !ruby/object:Overrides::ResourceOverrides
ProjectFeed: !ruby/object:Overrides::Terraform::ResourceOverride
autogen_async: false
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is necessary, I think it is the default

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right! I'm removing these.

@apsureda
Copy link
Contributor Author

I forgot to mention. This pull request addresses the following feature request: hashicorp/terraform-provider-google#6549

@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are.

Diff report:

Terraform GA: Diff ( 15 files changed, 2777 insertions(+), 2 deletions(-))
Terraform Beta: Diff ( 15 files changed, 2777 insertions(+), 2 deletions(-))
TF Conversion: Diff ( 4 files changed, 411 insertions(+))

@apsureda apsureda requested a review from megan07 July 18, 2020 21:23
@@ -0,0 +1,8 @@
// Remove the "folders/" prefix from the folder ID
Copy link
Contributor

Choose a reason for hiding this comment

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

This is one way to do it, and I'm not totally opposed. My suggestion was more along the line of editing the actual folder resource and adding a read-only attribute there for folder_id, which would essentially do this logic in that resource so that if we were ever to need this value again, as input into another resource, we'd have this value available to us. What do you think of that? Or would you prefer to keep the logic here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I initially tried to modify the folder attribute in the custom encoder. But the automated test failed due to a diff being found (the folder parameter was different than expected). So I ended up creating a computed folder_id attribute.
Did I miss something?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry! I was likely confusing - I meant adding folder_id to the google_folder resource schema and then doing a d.Set() around here in the actual resource.
In this way, instead of expecting the user to pass in the name folders/{{folder_id}} we'd just expect the {{folder_id}}. If we add it to the google_folder resource, it will make it easier on the user to get it from the Terraform resource. We should probably add it on the data source as well, but I think the two share some code, so that shouldn't be too bad.
Let me know if that makes sense to you!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The way I have implemented it now accepts both folders/12345 and 12345. So I think we are good.
Still, I think it would make sense to add the folder_id attribute to the google_folder resource. But I would not want this to be dependent on that.

url_param_only: true
description: |
The folder this feed should be created in.
- !ruby/object:Api::Type::String
Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I'm starting to understand this a bit better I think. Will the billing_project always be the project in feed_ouput_config.pubsub_destination.topic? I'm curious if we can make this a smoother, reusable solution for in the future. Something similar to supports_indirect_user_project_override, but a way to point to a resource's url that has the project we want. If that doesn't seem plausible, or the work seems too much, I'm not against what you have, it seems to work fine!

@apsureda
Copy link
Contributor Author

For some reason, I cannot reply directly to this comment, so I add my reply here.

You can actually have three different projects involved in a google_cloud_asset_project_feed:

  1. The project for which we want to receive notifications whenever a resource is modified in this project.
  2. The project where the PubSub topic will be located.
  3. The billing_project, which is the project whose cloud asset service account will be used as identity when writing messages to the PubSub topic (service-[PROJECT_NUMBER]@gcp-sa-cloudasset.iam.gserviceaccount.com).

When using the gcloud command, you indicate 1 using the --project parameter and 3 using the --billing-project parameter. 2 is implicit in the PubSub topic name. If you do not add the --billing-project parameter, --project will be used. I have replicated this same behaviour for consistency and flexibility.

In the case of the google_cloud_asset_organization_feed and google_cloud_asset_folder_feed, the billing_project is required. Otherwise, no X-Goog-User-Project header will be sent, and the request will result in an error:

Fail to use projects/PROJECT/topics/TOPIC
      as feed output destination. Error: User not authorized to perform this action.

And actually, in the gcloud command, it is the --billing-project parameter that must be used, since you must use only one among the project|folder|organization parameters. Maybe I should rename the project attribute in the google_cloud_asset_organization_feed and google_cloud_asset_folder_feed resources and call them billing_project instead?

@apsureda apsureda requested a review from megan07 July 21, 2020 07:40
@megan07
Copy link
Contributor

megan07 commented Jul 21, 2020

@apsureda - sure, I like the idea of using billing_project across all three resources for consistency. thanks!

Copy link
Contributor

@megan07 megan07 left a comment

Choose a reason for hiding this comment

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

If you wouldn't mind updating project to billing_project for consistency across the 3 feeds, I'll get this merged in. Thanks!

…ency across resources and with gcloud command
@modular-magician
Copy link
Collaborator

Hi! I'm the modular magician. Your PR generated some diffs in downstreams - here they are.

Diff report:

Terraform GA: Diff ( 15 files changed, 2793 insertions(+), 2 deletions(-))
Terraform Beta: Diff ( 15 files changed, 2793 insertions(+), 2 deletions(-))
TF Conversion: Diff ( 4 files changed, 411 insertions(+))

@apsureda
Copy link
Contributor Author

I renamed the project fields. Automated tests passed, and my own manual tests did too. I think we are good for the merge.
Thanks a lot for your patience. I have learnt a lot. My next PR will require less back and forth :-)

@apsureda apsureda requested a review from megan07 July 21, 2020 16:59
@megan07
Copy link
Contributor

megan07 commented Jul 21, 2020

Fixes hashicorp/terraform-provider-google#6549

@apsureda of course! thanks so much for your contribution - and for helping me learn more about the cloud asset feeds!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
4 participants