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

Generate DefaultObjectAccessControl in Terraform #630

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/terraform
2 changes: 1 addition & 1 deletion build/terraform-beta
11 changes: 8 additions & 3 deletions products/storage/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,15 @@ objects:
kind: 'storage#objectAccessControl'
base_url: b/{{bucket}}/defaultObjectAcl
self_link: b/{{bucket}}/defaultObjectAcl/{{entity}}
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/storage/docs/access-control/create-manage-lists'
api: 'https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls'
description: |
The ObjectAccessControls resources represent the Access Control Lists
(ACLs) for objects within Google Cloud Storage. ACLs let you specify
who has access to your data and to what extent.
The DefaultObjectAccessControls resources represent the Access Control
Lists (ACLs) applied to a new object within a Google Cloud Storage bucket
when no ACL was provided for that object. ACLs let you specify who has
access to your bucket contents and to what extent.

There are two roles that can be assigned to an entity:

Expand Down
18 changes: 16 additions & 2 deletions products/storage/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ overrides: !ruby/object:Provider::ResourceOverrides
- !ruby/object:Provider::Terraform::Examples
name: "storage_object_access_control_public_object"
primary_resource_id: "public_rule"
skip_test: true
vars:
bucket_name: "static-content-bucket"
object_name: "public-object"
Expand All @@ -36,7 +35,22 @@ overrides: !ruby/object:Provider::ResourceOverrides
object: !ruby/object:Provider::Terraform::PropertyOverride
description: The name of the object to apply the access control to.
DefaultObjectACL: !ruby/object:Provider::Terraform::ResourceOverride
exclude: true
name: "DefaultObjectAccessControl"
example:
- !ruby/object:Provider::Terraform::Examples
name: "storage_default_object_access_control_public"
primary_resource_id: "public_rule"
vars:
bucket_name: "static-content-bucket"
id_format: "{{bucket}}/{{entity}}"
import_format: ["{{bucket}}/{{entity}}"]
properties:
id: !ruby/object:Provider::Terraform::PropertyOverride
exclude: true
bucket: !ruby/object:Provider::Terraform::PropertyOverride
custom_expand: 'templates/terraform/custom_expand/resourceref_as_string.go.erb'
# This field is (unexpectedly) not returned from the API
ignore_read: true

# This is for copying files over
files: !ruby/object:Provider::Config::Files
Expand Down
1 change: 1 addition & 0 deletions provider/terraform/common~copy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@
-%>
'<%= dir -%>/<%= fname -%>': 'provider/terraform/utils/<%= fname -%>'
<% end -%>
'<%= dir -%>/test-fixtures/': 'provider/terraform/utils/test-fixtures'
'website': 'provider/terraform/website'
2 changes: 2 additions & 0 deletions provider/terraform/custom_code.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,13 @@ def oics_link
end

def substitute_test_paths(config)
config = config.gsub('../static/img/header-logo.png', 'test-fixtures/header-logo.png')
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does the png need to be checked into source control?

Copy link
Member Author

Choose a reason for hiding this comment

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

We need something to send up to our bucket, and I prefer sending "real" files up to just generating the file at test time. We already have a few static files for ssl certs and cloud functions, so I figure this image can be too.

Copy link
Contributor

Choose a reason for hiding this comment

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

As long as we keep the file sizes small and don't change them much it shouldn't be a big deal. Big or frequently changing binary files make git sad.

Copy link
Member Author

Choose a reason for hiding this comment

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

oh yup it is a 16x16 grey image very much on purpose haha. imo tossing 1-2 small images into vcs is fine, if it were any more/any larger it would 100% be time for a more future-proof solution

config = config.gsub('path/to/private.key', 'test-fixtures/ssl_cert/test.key')
config.gsub('path/to/certificate.crt', 'test-fixtures/ssl_cert/test.crt')
end

def substitute_example_paths(config)
config = config.gsub('../static/img/header-logo.png', '../static/header-logo.png')
config = config.gsub('path/to/private.key', '../static/ssl_cert/test.key')
config.gsub('path/to/certificate.crt', '../static/ssl_cert/test.crt')
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package google

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccStorageDefaultObjectAccessControl_basic(t *testing.T) {
t.Parallel()

bucketName := testBucketName()
resource.Test(t, resource.TestCase{
PreCheck: func() {
if errObjectAcl != nil {
panic(errObjectAcl)
}
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccStorageDefaultObjectAccessControlDestroy,
Steps: []resource.TestStep{
{
Config: testGoogleStorageDefaultObjectAccessControlBasic(bucketName, "READER", "allUsers"),
},
{
ResourceName: "google_storage_default_object_access_control.default",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccStorageDefaultObjectAccessControl_update(t *testing.T) {
t.Parallel()

bucketName := testBucketName()
resource.Test(t, resource.TestCase{
PreCheck: func() {
if errObjectAcl != nil {
panic(errObjectAcl)
}
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccStorageDefaultObjectAccessControlDestroy,
Steps: []resource.TestStep{
{
Config: testGoogleStorageDefaultObjectAccessControlBasic(bucketName, "READER", "allUsers"),
},
{
ResourceName: "google_storage_default_object_access_control.default",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testGoogleStorageDefaultObjectAccessControlBasic(bucketName, "OWNER", "allUsers"),
},
{
ResourceName: "google_storage_default_object_access_control.default",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccStorageDefaultObjectAccessControlDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)

for _, rs := range s.RootModule().Resources {
if rs.Type != "google_storage_bucket_acl" {
continue
}

bucket := rs.Primary.Attributes["bucket"]
entity := rs.Primary.Attributes["entity"]

rePairs, err := config.clientStorage.DefaultObjectAccessControls.List(bucket).Do()
if err != nil {
return fmt.Errorf("Can't list role entity acl for bucket %s", bucket)
}

for _, v := range rePairs.Items {
if v.Entity == entity {
return fmt.Errorf("found entity %s as role entity acl entry in bucket %s", entity, bucket)
}
}

}

return nil
}

func testGoogleStorageDefaultObjectAccessControlBasic(bucketName, role, entity string) string {
return fmt.Sprintf(`
resource "google_storage_bucket" "bucket" {
name = "%s"
}

resource "google_storage_default_object_access_control" "default" {
bucket = "${google_storage_bucket.bucket.name}"
role = "%s"
entity = "%s"
}
`, bucketName, role, entity)
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ without managing the bucket itself.
-> Note that for each object, its creator will have the `"OWNER"` role in addition
to the default ACL that has been defined.


For more information see
[the official documentation](https://cloud.google.com/storage/docs/access-control/lists)
and
[API](https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls).

-> Want fine-grained control over default object ACLs? Use `google_storage_default_object_access_control`
to control individual role entity pairs.

## Example Usage

Example creating a default object ACL on a bucket with one owner, and one reader.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resource "google_storage_default_object_access_control" "<%= ctx[:primary_resource_id] %>" {
bucket = "${google_storage_bucket.bucket.name}"
role = "READER"
entity = "allUsers"
}

resource "google_storage_bucket" "bucket" {
name = "<%= ctx[:vars]['bucket_name'] %>"
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ resource "google_storage_bucket" "bucket" {
resource "google_storage_bucket_object" "object" {
name = "<%= ctx[:vars]['object_name'] %>"
bucket = "${google_storage_bucket.bucket.name}"
source = "../static/img/header-logo.jpg"
source = "../static/img/header-logo.png"
}