lib/gcloud/resource_manager/project.rb in gcloud-0.11.0 vs lib/gcloud/resource_manager/project.rb in gcloud-0.12.0
- old
+ new
@@ -12,13 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
require "time"
-require "gcloud/resource_manager/errors"
require "gcloud/resource_manager/project/list"
require "gcloud/resource_manager/project/updater"
+require "gcloud/resource_manager/policy"
module Gcloud
module ResourceManager
##
# # Project
@@ -38,45 +38,45 @@
# p.labels["env"] = "production"
# end
#
class Project
##
- # @private The Connection object.
- attr_accessor :connection
+ # @private The Service object.
+ attr_accessor :service
##
# @private The Google API Client object.
attr_accessor :gapi
##
# @private Create an empty Project object.
def initialize
- @connection = nil
- @gapi = {}
+ @service = nil
+ @gapi = Gcloud::ResourceManager::Service::API::Project.new
end
##
# The unique, user-assigned ID of the project. It must be 6 to 30
# lowercase letters, digits, or hyphens. It must start with a letter.
# Trailing hyphens are prohibited. e.g. tokyo-rain-123
#
def project_id
- @gapi["projectId"]
+ @gapi.project_id
end
##
# The number uniquely identifying the project. e.g. 415104041262
#
def project_number
- @gapi["projectNumber"]
+ @gapi.project_number
end
##
# The user-assigned name of the project.
#
def name
- @gapi["name"]
+ @gapi.name
end
##
# Updates the user-assigned name of the project. This field is optional
# and can remain unset.
@@ -91,18 +91,13 @@
# resource_manager = gcloud.resource_manager
# project = resource_manager.project "tokyo-rain-123"
# project.name = "My Project"
#
def name= new_name
- ensure_connection!
- @gapi["name"] = new_name
- resp = connection.update_project @gapi
- if resp.success?
- @gapi = resp.data
- else
- fail ApiError.from_response(resp)
- end
+ ensure_service!
+ @gapi.name = new_name
+ @gapi = service.update_project @gapi
end
##
# The labels associated with this project.
#
@@ -136,12 +131,11 @@
# project.labels do |labels|
# labels["env"] = "production"
# end
#
def labels
- labels = @gapi["labels"]
- labels = labels.to_hash if labels.respond_to? :to_hash
+ labels = @gapi.labels.to_h
if block_given?
yielded_labels = labels.dup
yield yielded_labels
self.labels = yielded_labels if yielded_labels != labels # changed
else
@@ -168,44 +162,39 @@
# resource_manager = gcloud.resource_manager
# project = resource_manager.project "tokyo-rain-123"
# project.labels = { "env" => "production" }
#
def labels= new_labels
- ensure_connection!
- @gapi["labels"] = new_labels
- resp = connection.update_project @gapi
- if resp.success?
- @gapi = resp.data
- else
- fail ApiError.from_response(resp)
- end
+ ensure_service!
+ @gapi.labels = new_labels
+ @gapi = service.update_project @gapi
end
##
# The time that this project was created.
#
def created_at
- Time.parse @gapi["createTime"]
+ Time.parse @gapi.create_time
rescue
nil
end
##
# The project lifecycle state.
#
# Possible values are:
# * `ACTIVE` - The normal and active state.
- # * `LIFECYCLE_STATE_UNSPECIFIED` - Unspecified state. This is only
- # used/useful for distinguishing unset values.
# * `DELETE_REQUESTED` - The project has been marked for deletion by the
- # user (by invoking DeleteProject) or by the system (Google Cloud
- # Platform). This can generally be reversed by invoking UndeleteProject.
+ # user (by invoking ##delete) or by the system (Google Cloud
+ # Platform). This can generally be reversed by invoking {#undelete}.
# * `DELETE_IN_PROGRESS` - The process of deleting the project has begun.
# Reversing the deletion is no longer possible.
+ # * `LIFECYCLE_STATE_UNSPECIFIED` - Unspecified state. This is only
+ # used/useful for distinguishing unset values.
#
def state
- @gapi["lifecycleState"]
+ @gapi.lifecycle_state
end
##
# Checks if the state is `ACTIVE`.
def active?
@@ -253,16 +242,14 @@
# end
#
def update
updater = Updater.from_project self
yield updater
- resp = connection.update_project updater.gapi
- if resp.success?
- @gapi = resp.data
- else
- fail ApiError.from_response(resp)
+ if updater.gapi.to_h != @gapi.to_h # changed
+ @gapi = service.update_project updater.gapi
end
+ self
end
##
# Reloads the project (with updated state) from the Google Cloud Resource
# Manager service.
@@ -274,16 +261,11 @@
# resource_manager = gcloud.resource_manager
# project = resource_manager.project "tokyo-rain-123"
# project.reload!
#
def reload!
- resp = connection.get_project project_id
- if resp.success?
- @gapi = resp.data
- else
- fail ApiError.from_response(resp)
- end
+ @gapi = service.get_project project_id
end
alias_method :refresh!, :reload!
##
# Marks the project for deletion. This method will only affect the project
@@ -315,17 +297,13 @@
# project.delete
# project.active? #=> false
# project.delete_requested? #=> true
#
def delete
- resp = connection.delete_project project_id
- if resp.success?
- reload!
- true
- else
- fail ApiError.from_response(resp)
- end
+ service.delete_project project_id
+ reload!
+ true
end
##
# Restores the project. You can only use this method for a project that
# has a lifecycle state of `DELETE_REQUESTED`. After deletion starts, as
@@ -344,114 +322,116 @@
# project.undelete
# project.delete_requested? #=> false
# project.active? #=> true
#
def undelete
- resp = connection.undelete_project project_id
- if resp.success?
- reload!
- true
- else
- fail ApiError.from_response(resp)
- end
+ service.undelete_project project_id
+ reload!
+ true
end
##
- # Gets the [Cloud IAM](https://cloud.google.com/iam/) access control
- # policy. Returns a hash that conforms to the following structure:
+ # Gets and updates the [Cloud IAM](https://cloud.google.com/iam/) access
+ # control policy for this project.
#
- # {
- # "bindings" => [{
- # "role" => "roles/viewer",
- # "members" => ["serviceAccount:your-service-account"]
- # }],
- # "version" => 0,
- # "etag" => "CAE="
- # }
- #
# @see https://cloud.google.com/iam/docs/managing-policies Managing
# Policies
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
+ # projects.setIamPolicy
#
# @param [Boolean] force Force load the latest policy when `true`.
# Otherwise the policy will be memoized to reduce the number of API
# calls made. The default is `false`.
#
- # @return [Hash] See description
+ # @yield [policy] A block for updating the policy. The latest policy will
+ # be read from the service and passed to the block. After the block
+ # completes, the modified policy will be written to the service.
+ # @yieldparam [Policy] policy the current Cloud IAM Policy for this
+ # project
#
- # @example Policy values are memoized by default:
+ # @return [Policy] the current Cloud IAM Policy for this project
+ #
+ # @example Policy values are memoized to reduce the number of API calls:
# require "gcloud"
#
# gcloud = Gcloud.new
# resource_manager = gcloud.resource_manager
# project = resource_manager.project "tokyo-rain-123"
- # policy = project.policy
#
- # puts policy["bindings"]
- # puts policy["version"]
- # puts policy["etag"]
+ # policy = project.policy # API call
+ # policy_2 = project.policy # No API call
#
- # @example Use the `force` option to retrieve the latest policy:
+ # @example Use `force` to retrieve the latest policy from the service:
# require "gcloud"
#
# gcloud = Gcloud.new
# resource_manager = gcloud.resource_manager
# project = resource_manager.project "tokyo-rain-123"
- # policy = project.policy force: true
#
+ # policy = project.policy force: true # API call
+ # policy_2 = project.policy force: true # API call
+ #
+ # @example Update the policy by passing a block:
+ # require "gcloud"
+ #
+ # gcloud = Gcloud.new
+ # resource_manager = gcloud.resource_manager
+ # project = resource_manager.project "tokyo-rain-123"
+ #
+ # policy = project.policy do |p|
+ # p.add "roles/owner", "user:owner@example.com"
+ # end # 2 API calls
+ #
def policy force: false
- @policy = nil if force
+ @policy = nil if force || block_given?
@policy ||= begin
- ensure_connection!
- resp = connection.get_policy project_id
- fail ApiError.from_response(resp) unless resp.success?
- policy = resp.data
- policy = policy.to_hash if policy.respond_to? :to_hash
- policy
+ ensure_service!
+ gapi = service.get_policy project_id
+ Policy.from_gapi gapi
end
+ return @policy unless block_given?
+ p = @policy.deep_dup
+ yield p
+ self.policy = p
end
##
- # Sets the [Cloud IAM](https://cloud.google.com/iam/) access control
- # policy.
+ # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
+ # policy for this project. The policy should be read from {#policy}.
+ # See {Gcloud::ResourceManager::Policy} for an explanation of the policy
+ # `etag` property and how to modify policies.
#
+ # You can also update the policy by passing a block to {#policy}, which
+ # will call this method internally after the block completes.
+ #
# @see https://cloud.google.com/iam/docs/managing-policies Managing
# Policies
+ # @see https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/setIamPolicy
+ # projects.setIamPolicy
#
- # @param [String] new_policy A hash that conforms to the following
- # structure:
+ # @param [Policy] new_policy a new or modified Cloud IAM Policy for this
+ # project
#
- # {
- # "bindings" => [{
- # "role" => "roles/viewer",
- # "members" => ["serviceAccount:your-service-account"]
- # }]
- # }
- #
# @example
# require "gcloud"
#
# gcloud = Gcloud.new
# resource_manager = gcloud.resource_manager
# project = resource_manager.project "tokyo-rain-123"
#
- # viewer_policy = {
- # "bindings" => [{
- # "role" => "roles/viewer",
- # "members" => ["serviceAccount:your-service-account"]
- # }]
- # }
- # project.policy = viewer_policy
+ # policy = project.policy # API call
#
+ # policy.add "roles/owner", "user:owner@example.com"
+ #
+ # project.policy = policy # API call
+ #
def policy= new_policy
- ensure_connection!
- resp = connection.set_policy project_id, new_policy
- if resp.success?
- @policy = resp.data
- @policy = @policy.to_hash if @policy.respond_to? :to_hash
- else
- fail ApiError.from_response(resp)
- end
+ ensure_service!
+ gapi = service.set_policy project_id, new_policy.to_gapi
+ # Convert symbols to strings for backwards compatibility.
+ # This will go away when we add a ResourceManager::Policy class.
+ @policy = Policy.from_gapi gapi
end
##
# Tests the specified permissions against the [Cloud
# IAM](https://cloud.google.com/iam/) access control policy.
@@ -476,33 +456,29 @@
# perms.include? "resourcemanager.projects.get" #=> true
# perms.include? "resourcemanager.projects.delete" #=> false
#
def test_permissions *permissions
permissions = Array(permissions).flatten
- ensure_connection!
- resp = connection.test_permissions project_id, permissions
- if resp.success?
- Array(resp.data["permissions"])
- else
- fail ApiError.from_response(resp)
- end
+ ensure_service!
+ gapi = service.test_permissions project_id, permissions
+ gapi.permissions
end
##
# @private New Change from a Google API Client object.
- def self.from_gapi gapi, connection
+ def self.from_gapi gapi, service
new.tap do |p|
p.gapi = gapi
- p.connection = connection
+ p.service = service
end
end
protected
##
- # Raise an error unless an active connection is available.
- def ensure_connection!
- fail "Must have active connection" unless connection
+ # Raise an error unless an active service is available.
+ def ensure_service!
+ fail "Must have active connection" unless service
end
end
end
end