diff --git a/app/controllers/google_api/authorizations_controller.rb b/app/controllers/google_api/authorizations_controller.rb index 4b315181b7d691729bf93ad56b206ba8044b4437..00b0c1287114a62ba4cc58d894f89fd11cb87f0d 100644 --- a/app/controllers/google_api/authorizations_controller.rb +++ b/app/controllers/google_api/authorizations_controller.rb @@ -1,9 +1,9 @@ module GoogleApi class AuthorizationsController < ApplicationController def callback - session[GoogleApi::CloudPlatform::Client.token_in_session] = - GoogleApi::Authentication.new(nil, callback_google_api_authorizations_url) - .get_token(params[:code]) + session[GoogleApi::CloudPlatform::Client.session_key_for_token] = + GoogleApi::CloudPlatform::Client.new(nil, callback_google_api_authorizations_url) + .get_token(params[:code]) if params[:state] redirect_to params[:state] diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb index 61bd28c65fe572137a67fdca9e7de0566f380587..840c623e778d5de2328dfecf532b25c2fdcb3f14 100644 --- a/app/controllers/projects/clusters_controller.rb +++ b/app/controllers/projects/clusters_controller.rb @@ -1,12 +1,17 @@ class Projects::ClustersController < Projects::ApplicationController before_action :cluster, except: [:login, :index, :new, :create] before_action :authorize_google_api, except: [:login] + # before_action :cluster_creation_lock, only: [:update, :destroy] # before_action :authorize_admin_clusters! # TODO: Authentication def login begin - @authorize_url = api_client.authorize_url - rescue GoogleApi::Authentication::ConfigMissingError + @authorize_url = GoogleApi::CloudPlatform::Client.new( + nil, + callback_google_api_authorizations_url, + state: namespace_project_clusters_url.to_s + ).authorize_url + rescue GoogleApi::Auth::ConfigMissingError # Show an alert message that gitlab.yml is not configured properly end end @@ -20,28 +25,29 @@ class Projects::ClustersController < Projects::ApplicationController end def new + @cluster = project.clusters.new end def create - begin - Ci::CreateClusterService.new(project, current_user, params) - .create_cluster_on_gke(api_client) - rescue Ci::CreateClusterService::UnexpectedOperationError => e - # TODO: error - puts "#{self.class.name} - #{__callee__}: e: #{e}" - end + @cluster = Ci::CreateClusterService + .new(project, current_user, cluster_params) + .execute(token_in_session) - redirect_to project_clusters_path(project) + if @cluster.persisted? + ClusterCreationWorker.perform_async(@cluster.id) + redirect_to project_clusters_path(project) + else + render :new + end end - ## - # Return - # @status: The current status of the operation. - # @status_message: If an error has occurred, a textual description of the error. - def creation_status + def status respond_to do |format| format.json do - render json: cluster.creation_status(session[GoogleApi::CloudPlatform::Client.token_in_session]) + render json: { + status: cluster.status, # The current status of the operation. + status_reason: cluster.status_reason # If an error has occurred, a textual description of the error. + } end end end @@ -50,24 +56,9 @@ class Projects::ClustersController < Projects::ApplicationController end def update - Ci::Cluster.transaction do - if params['enabled'] == 'true' - - cluster.service.attributes = { - active: true, - api_url: cluster.endpoint, - ca_pem: cluster.ca_cert, - namespace: cluster.project_namespace, - token: cluster.token - } - - cluster.service.save! - else - cluster.service.update(active: false) - end - - cluster.update(enabled: params['enabled']) - end + Ci::UpdateClusterService + .new(project, current_user, cluster_params) + .execute(cluster) render :edit end @@ -88,18 +79,27 @@ class Projects::ClustersController < Projects::ApplicationController @cluster ||= project.clusters.find(params[:id]) end - def api_client - @api_client ||= - GoogleApi::CloudPlatform::Client.new( - session[GoogleApi::CloudPlatform::Client.token_in_session], - callback_google_api_authorizations_url, - state: namespace_project_clusters_url.to_s - ) + def cluster_params + params.require(:cluster) + .permit(:gcp_project_id, :cluster_zone, :cluster_name, :cluster_size, + :machine_type, :project_namespace, :enabled) end def authorize_google_api - unless session[GoogleApi::CloudPlatform::Client.token_in_session] + unless token_in_session redirect_to action: 'login' end end + + def token_in_session + @token_in_session ||= session[GoogleApi::CloudPlatform::Client.session_key_for_token] + end + + def cluster_creation_lock + if cluster.on_creation? + redirect_to edit_project_cluster_path(project, cluster), + status: :forbidden, + alert: _("You can not modify cluster during creation") + end + end end diff --git a/app/models/ci/cluster.rb b/app/models/ci/cluster.rb index afb70a3ff4aaee75a6fcba27a6ac7de27d17e956..d1b69c19965608df39017d690c40537a688cf6d6 100644 --- a/app/models/ci/cluster.rb +++ b/app/models/ci/cluster.rb @@ -1,105 +1,45 @@ module Ci class Cluster < ActiveRecord::Base extend Gitlab::Ci::Model - include ReactiveCaching - - self.reactive_cache_key = ->(cluster) { [cluster.class.model_name.singular, cluster.project_id, cluster.id] } belongs_to :project belongs_to :user belongs_to :service attr_encrypted :password, - mode: :per_attribute_iv_and_salt, - insecure_mode: true, - key: Gitlab::Application.secrets.db_key_base, - algorithm: 'aes-256-cbc' - - # after_save :clear_reactive_cache! - - def creation_status(access_token) - with_reactive_cache(access_token) do |operation| - { - status: operation[:status], - status_message: operation[:status_message] - } - end - end - - def calculate_reactive_cache(access_token) - return { status: 'INTEGRATED' } if service # If it's already done, we don't need to continue the following process - - api_client = GoogleApi::CloudPlatform::Client.new(access_token, nil) - operation = api_client.projects_zones_operations(gcp_project_id, cluster_zone, gcp_operation_id) - - return { status_message: 'Failed to get a status' } unless operation - - if operation.status == 'DONE' - # Get cluster details (end point, etc) - gke_cluster = api_client.projects_zones_clusters_get( - gcp_project_id, cluster_zone, cluster_name - ) - - return { status_message: 'Failed to get a cluster info on gke' } unless gke_cluster - - # Get k8s token - token = '' - KubernetesService.new.tap do |ks| - ks.api_url = 'https://' + gke_cluster.endpoint - ks.ca_pem = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) - ks.username = gke_cluster.master_auth.username - ks.password = gke_cluster.master_auth.password - secrets = ks.read_secrets - secrets.each do |secret| - name = secret.dig('metadata', 'name') - if /default-token/ =~ name - token_base64 = secret.dig('data', 'token') - token = Base64.decode64(token_base64) - break - end - end - end - - return { status_message: 'Failed to get a default token on kubernetes' } unless token - - # k8s endpoint, ca_cert - endpoint = 'https://' + gke_cluster.endpoint - cluster_ca_certificate = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) - - begin - Ci::Cluster.transaction do - # Update service - kubernetes_service.attributes = { - active: true, - api_url: endpoint, - ca_pem: cluster_ca_certificate, - namespace: project_namespace, - token: token - } - - kubernetes_service.save! - - # Save info in cluster record - update( - enabled: true, - service: kubernetes_service, - username: gke_cluster.master_auth.username, - password: gke_cluster.master_auth.password, - token: token, - ca_cert: cluster_ca_certificate, - endpoint: endpoint, - ) - end - rescue ActiveRecord::RecordInvalid => exception - return { status_message: 'Failed to setup integration' } - end - end - - operation.to_h + mode: :per_attribute_iv_and_salt, + insecure_mode: true, + key: Gitlab::Application.secrets.db_key_base, + algorithm: 'aes-256-cbc' + + attr_encrypted :kubernetes_token, + mode: :per_attribute_iv_and_salt, + insecure_mode: true, + key: Gitlab::Application.secrets.db_key_base, + algorithm: 'aes-256-cbc' + + attr_encrypted :gcp_token, + mode: :per_attribute_iv_and_salt, + insecure_mode: true, + key: Gitlab::Application.secrets.db_key_base, + algorithm: 'aes-256-cbc' + + enum status: { + unknown: nil, + scheduled: 1, + creating: 2, + created: 3, + errored: 4 + } + + def error!(reason) + update!(status: statuses[:errored], + status_reason: reason, + gcp_token: nil) end - def kubernetes_service - @kubernetes_service ||= project.find_or_initialize_service('kubernetes') + def on_creation? + scheduled? || creating? end end end diff --git a/app/services/ci/create_cluster_service.rb b/app/services/ci/create_cluster_service.rb index edae245ec386b1a443ac36506c65b6e7dddc24d6..86820706831724e0562c36e024e587322549d2bb 100644 --- a/app/services/ci/create_cluster_service.rb +++ b/app/services/ci/create_cluster_service.rb @@ -1,29 +1,10 @@ module Ci class CreateClusterService < BaseService - UnexpectedOperationError = Class.new(StandardError) - - def create_cluster_on_gke(api_client) - # Create a cluster on GKE - operation = api_client.projects_zones_clusters_create( - params['gcp_project_id'], params['cluster_zone'], params['cluster_name'], - cluster_size: params['cluster_size'], machine_type: params['machine_type'] - ) - - if operation&.status != ('RUNNING' || 'PENDING') - raise UnexpectedOperationError.new(operation&.status_message) - end - - api_client.parse_self_link(operation.self_link).tap do |project_id, zone, operation_id| - project.clusters.create(user: current_user, - gcp_project_id: params['gcp_project_id'], - cluster_zone: params['cluster_zone'], - cluster_name: params['cluster_name'], - project_namespace: params['project_namespace'], - gcp_operation_id: operation_id).tap do |cluster| - # Start status polling. When the operation finish, create KubernetesService. - cluster.creation_status(api_client.access_token) - end - end + def execute(access_token) + project.clusters.create( + params.merge(user: current_user, + status: Ci::Cluster.statuses[:scheduled], + gcp_token: access_token)) end end end diff --git a/app/services/ci/integrate_cluster_service.rb b/app/services/ci/integrate_cluster_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..d5b1ccd345dd168f6279b580e61c16bc976a2b72 --- /dev/null +++ b/app/services/ci/integrate_cluster_service.rb @@ -0,0 +1,36 @@ +module Ci + class IntegrateClusterService + def execute(cluster, endpoint, ca_cert, token, username, password) + kubernetes_service ||= cluster.project.find_or_initialize_service('kubernetes') + + Ci::Cluster.transaction do + # Update service + kubernetes_service.attributes = { + active: true, + api_url: endpoint, + ca_pem: ca_cert, + namespace: cluster.project_namespace, + token: token + } + + kubernetes_service.save! + + # Save info in cluster record + cluster.update!( + enabled: true, + service: kubernetes_service, + username: username, + password: password, + kubernetes_token: token, + ca_cert: ca_cert, + endpoint: endpoint, + gcp_token: nil, + status: Ci::Cluster.statuses[:created] + ) + end + + rescue ActiveRecord::RecordInvalid => e + cluster.error!("Failed to integrate cluster into kubernetes_service: #{e.message}") + end + end +end diff --git a/app/services/ci/update_cluster_service.rb b/app/services/ci/update_cluster_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..0b458e27b901b34bcb3c7f54f338841b55c1bad8 --- /dev/null +++ b/app/services/ci/update_cluster_service.rb @@ -0,0 +1,26 @@ +module Ci + class UpdateClusterService < BaseService + def execute(cluster) + Ci::Cluster.transaction do + if params['enabled'] == 'true' + + cluster.service.attributes = { + active: true, + api_url: cluster.endpoint, + ca_pem: cluster.ca_cert, + namespace: cluster.project_namespace, + token: cluster.kubernetes_token + } + + cluster.service.save! + else + cluster.service.update(active: false) + end + + cluster.update!(enabled: params['enabled']) + end + rescue ActiveRecord::RecordInvalid => e + cluster.errors.add(:base, e.message) + end + end +end diff --git a/app/views/projects/clusters/_form.html.haml b/app/views/projects/clusters/_form.html.haml index cf1a087ed13846f3168012e7083a4492a3e6da69..10a4b4d8ba89f46525b62d6ec5bf31d4ebf710a8 100644 --- a/app/views/projects/clusters/_form.html.haml +++ b/app/views/projects/clusters/_form.html.haml @@ -4,7 +4,7 @@ -link_to_help_page = link_to(s_('ClusterIntegration|help page'), help_page_path('TODO'), target: '_blank', rel: 'noopener noreferrer') = s_('ClusterIntegration|Use our %{link_to_help_page} on cluster integration.').html_safe % { link_to_help_page: link_to_help_page} - = form_for 'cluster' do |field| + = form_for [@project.namespace.becomes(Namespace), @project, @cluster] do |field| .form-group = field.label :cluster_name = field.text_field :cluster_name, class: 'form-control' @@ -32,4 +32,5 @@ .form-group = field.submit s_('ClusterIntegration|Create cluster'), class: 'btn btn-save' - = link_to "Create on Google Container Engine", namespace_project_clusters_path(@project.namespace, @project, cluster_name: "gke-test-creation#{Random.rand(100)}", gcp_project_id: 'gitlab-internal-153318', cluster_zone: 'us-central1-a', cluster_size: '1', project_namespace: 'aaa', machine_type: '???'), method: :post \ No newline at end of file + -# TODO: Remove before merge + = link_to "Create on Google Container Engine", namespace_project_clusters_path(@project.namespace, @project, cluster: {cluster_name: "gke-test-creation#{Random.rand(100)}", gcp_project_id: 'gitlab-internal-153318', cluster_zone: 'us-central1-a', cluster_size: '1', project_namespace: 'aaa', machine_type: '???'}), method: :post \ No newline at end of file diff --git a/app/views/projects/clusters/edit.html.haml b/app/views/projects/clusters/edit.html.haml index ee7c8896f6841d2e03220cbbf0d1d767be2dc423..7f8400d9ea1d92f8d3a97762bee90de4485e6477 100644 --- a/app/views/projects/clusters/edit.html.haml +++ b/app/views/projects/clusters/edit.html.haml @@ -2,7 +2,15 @@ edit/show cluster %br = @cluster.inspect = @cluster.service.inspect -= link_to "Enable", namespace_project_cluster_path(@project.namespace, @project, @cluster.id, enabled: 'true'), method: :put -= link_to "Disable", namespace_project_cluster_path(@project.namespace, @project, @cluster.id, enabled: 'false'), method: :put -= link_to "Soft-delete the cluster", namespace_project_cluster_path(@project.namespace, @project, @cluster.id), method: :delete -= link_to 'Check status', creation_status_namespace_project_cluster_path(@cluster.project.namespace, @cluster.project, @cluster.id), :remote => true +- unless @cluster.on_creation? + = link_to "Enable", namespace_project_cluster_path(@project.namespace, @project, @cluster.id, cluster: {enabled: 'true'}), method: :put + = link_to "Disable", namespace_project_cluster_path(@project.namespace, @project, @cluster.id, cluster: {enabled: 'false'}), method: :put + = link_to "Soft-delete the cluster", namespace_project_cluster_path(@project.namespace, @project, @cluster.id), method: :delete +-# status GET +-# status: The current status of the operation. +-# status_reason: If an error has occurred, a textual description of the error. += link_to 'Check status', status_namespace_project_cluster_path(@cluster.project.namespace, @cluster.project, @cluster.id), :remote => true +-# simply rendering error, if it happened +- if @cluster.status_reason + %p= status_reason +-# Even if we got an error during the creation process, we don't delete cluster objects automatically, because we don't have a method to delete the cluster on gke. So users move to edit page from new page **regardless of validation errors**, and they have to delete the record manually. This is for giving users headsup that a new cluster might remain in gke. /cc @ayufan diff --git a/app/workers/cluster_creation_worker.rb b/app/workers/cluster_creation_worker.rb new file mode 100644 index 0000000000000000000000000000000000000000..0b547089b94e8653ee93ff8b39278d82a20bfbc5 --- /dev/null +++ b/app/workers/cluster_creation_worker.rb @@ -0,0 +1,47 @@ +class ClusterCreationWorker + include Sidekiq::Worker + include DedicatedSidekiqQueue + + def perform(cluster_id) + cluster = Ci::Cluster.find_by_id(cluster_id) + + unless cluster + return Rails.logger.error "Cluster object is not found; #{cluster_id}" + end + + api_client = + GoogleApi::CloudPlatform::Client.new(cluster.gcp_token, nil) + + operation = api_client.projects_zones_clusters_create( + cluster.gcp_project_id, + cluster.cluster_zone, + cluster.cluster_name, + cluster.cluster_size, + machine_type: cluster.machine_type + ) + + if operation.is_a?(StandardError) + return cluster.error!("Failed to request to CloudPlatform; #{operation.message}") + end + + unless operation.status == 'RUNNING' || operation.status == 'PENDING' + return cluster.error!("Operation status is unexpected; #{operation.status_message}") + end + + operation_id = api_client.parse_operation_id(operation.self_link) + + unless operation_id + return cluster.error!('Can not find operation_id from self_link') + end + + if cluster.update(status: Ci::Cluster.statuses[:creating], + gcp_operation_id: operation_id) + WaitForClusterCreationWorker.perform_in( + WaitForClusterCreationWorker::INITIAL_INTERVAL, + cluster.id + ) + else + return cluster.error!("Failed to update cluster record; #{cluster.errors}") + end + end +end diff --git a/app/workers/wait_for_cluster_creation_worker.rb b/app/workers/wait_for_cluster_creation_worker.rb new file mode 100644 index 0000000000000000000000000000000000000000..e0dce5a60cd389a42a7465f234eb9eeb58cf55e9 --- /dev/null +++ b/app/workers/wait_for_cluster_creation_worker.rb @@ -0,0 +1,85 @@ +class WaitForClusterCreationWorker + include Sidekiq::Worker + include DedicatedSidekiqQueue + + INITIAL_INTERVAL = 2.minutes + EAGER_INTERVAL = 10.seconds + TIMEOUT = 20.minutes + + def perform(cluster_id) + cluster = Ci::Cluster.find_by_id(cluster_id) + + unless cluster + return Rails.logger.error "Cluster object is not found; #{cluster_id}" + end + + api_client = + GoogleApi::CloudPlatform::Client.new(cluster.gcp_token, nil) + + operation = api_client.projects_zones_operations( + cluster.gcp_project_id, + cluster.cluster_zone, + cluster.gcp_operation_id + ) + + if operation.is_a?(StandardError) + return cluster.error!("Failed to request to CloudPlatform; #{operation.message}") + end + + case operation.status + when 'DONE' + integrate(api_client, cluster) + when 'RUNNING' + if Time.now < operation.start_time.to_time + TIMEOUT + WaitForClusterCreationWorker.perform_in(EAGER_INTERVAL, cluster.id) + else + return cluster.error!("Cluster creation time exceeds timeout; #{TIMEOUT}") + end + else + return cluster.error!("Unexpected operation status; #{operation.status_message}") + end + end + + def integrate(api_client, cluster) + # Get cluster details (end point, etc) + gke_cluster = api_client.projects_zones_clusters_get( + cluster.gcp_project_id, + cluster.cluster_zone, + cluster.cluster_name + ) + + if gke_cluster.is_a?(StandardError) + return cluster.error!("Failed to request to CloudPlatform; #{gke_cluster.message}") + end + + # Get k8s token + kubernetes_token = '' + KubernetesService.new.tap do |ks| + ks.api_url = 'https://' + gke_cluster.endpoint + ks.ca_pem = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) + ks.username = gke_cluster.master_auth.username + ks.password = gke_cluster.master_auth.password + secrets = ks.read_secrets + secrets.each do |secret| + name = secret.dig('metadata', 'name') + if /default-token/ =~ name + token_base64 = secret.dig('data', 'token') + kubernetes_token = Base64.decode64(token_base64) + break + end + end + end + + unless kubernetes_token + return cluster.error!('Failed to get a default token of kubernetes') + end + + # k8s endpoint, ca_cert + endpoint = 'https://' + gke_cluster.endpoint + ca_cert = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) + username = gke_cluster.master_auth.username + password = gke_cluster.master_auth.password + + Ci::IntegrateClusterService.new.execute(cluster, endpoint, ca_cert, kubernetes_token, username, password) + end +end diff --git a/config/routes/project.rb b/config/routes/project.rb index 396681d272ab2cd1d8ed334ea85c43921e03b16f..a01e26b2fe36cf0d183eea1f8b3aa5dcf5a0ae17 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -189,7 +189,7 @@ constraints(ProjectUrlConstrainer.new) do end member do - get :creation_status, format: :json + get :status, format: :json end end diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index d169c38a6931e7d949a38543c2c700d8d254ae3d..1af90d0a3619b98ce3b0bae06406cddda2e8c8b2 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -62,3 +62,5 @@ - [update_user_activity, 1] - [propagate_service_template, 1] - [background_migration, 1] + - [cluster_creation, 1] + - [wait_for_cluster_creation, 1] diff --git a/db/migrate/20170924094327_create_ci_clusters.rb b/db/migrate/20170924094327_create_ci_clusters.rb index 2663130c7e6055d26b0a76df878806dda61f2b27..798c8e03b3781af724b99155ccc395de2f8ddf52 100644 --- a/db/migrate/20170924094327_create_ci_clusters.rb +++ b/db/migrate/20170924094327_create_ci_clusters.rb @@ -9,6 +9,8 @@ class CreateCiClusters < ActiveRecord::Migration # General t.boolean :enabled, default: true + t.integer :status + t.string :status_reason # k8s integration specific t.string :project_namespace @@ -16,9 +18,10 @@ class CreateCiClusters < ActiveRecord::Migration # Cluster details t.string :endpoint t.text :ca_cert - t.string :token + t.string :encrypted_kubernetes_token + t.string :encrypted_kubernetes_token_salt + t.string :encrypted_kubernetes_token_iv t.string :username - t.string :password t.string :encrypted_password t.string :encrypted_password_salt t.string :encrypted_password_iv @@ -27,7 +30,12 @@ class CreateCiClusters < ActiveRecord::Migration t.string :gcp_project_id t.string :cluster_zone t.string :cluster_name + t.string :cluster_size + t.string :machine_type t.string :gcp_operation_id + t.string :encrypted_gcp_token + t.string :encrypted_gcp_token_salt + t.string :encrypted_gcp_token_iv t.datetime_with_timezone :created_at, null: false t.datetime_with_timezone :updated_at, null: false diff --git a/db/schema.rb b/db/schema.rb index af5367113a2e6ec0bfddaa5105d2a2419d25d744..de844583d56fe486826678f34f11205997a875ee 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -272,19 +272,27 @@ ActiveRecord::Schema.define(version: 20170924094327) do t.integer "user_id", null: false t.integer "service_id" t.boolean "enabled", default: true + t.integer "status" + t.string "status_reason" t.string "project_namespace" t.string "endpoint" t.text "ca_cert" - t.string "token" + t.string "encrypted_kubernetes_token" + t.string "encrypted_kubernetes_token_salt" + t.string "encrypted_kubernetes_token_iv" t.string "username" - t.string "password" t.string "encrypted_password" t.string "encrypted_password_salt" t.string "encrypted_password_iv" t.string "gcp_project_id" t.string "cluster_zone" t.string "cluster_name" + t.string "cluster_size" + t.string "machine_type" t.string "gcp_operation_id" + t.string "encrypted_gcp_token" + t.string "encrypted_gcp_token_salt" + t.string "encrypted_gcp_token_iv" t.datetime "created_at", null: false t.datetime "updated_at", null: false end diff --git a/lib/google_api/authentication.rb b/lib/google_api/auth.rb similarity index 98% rename from lib/google_api/authentication.rb rename to lib/google_api/auth.rb index 4c9016e108501aaeec373c3c97507d8db2ee0cd6..92787b87ac6c1d3b05d08d502aec18640e810bb1 100644 --- a/lib/google_api/authentication.rb +++ b/lib/google_api/auth.rb @@ -1,5 +1,5 @@ module GoogleApi - class Authentication + class Auth attr_reader :access_token, :redirect_uri, :state ConfigMissingError = Class.new(StandardError) diff --git a/lib/google_api/cloud_platform/client.rb b/lib/google_api/cloud_platform/client.rb index 0bc306a24e66498cb108343fca718b9e3d6f8f9d..74ae5e16ab201884bdab754dd2311987de663769 100644 --- a/lib/google_api/cloud_platform/client.rb +++ b/lib/google_api/cloud_platform/client.rb @@ -2,9 +2,9 @@ require 'google/apis/container_v1' module GoogleApi module CloudPlatform - class Client < GoogleApi::Authentication + class Client < GoogleApi::Auth class << self - def token_in_session + def session_key_for_token :cloud_platform_access_token end end @@ -13,20 +13,14 @@ module GoogleApi 'https://www.googleapis.com/auth/cloud-platform' end - ## - # Exception - # Google::Apis::ClientError: - # Google::Apis::AuthorizationError: - ## - def projects_zones_clusters_get(project_id, zone, cluster_id) service = Google::Apis::ContainerV1::ContainerService.new service.authorization = access_token begin cluster = service.get_zone_cluster(project_id, zone, cluster_id) - rescue Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return nil + rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e + return e end puts "#{self.class.name} - #{__callee__}: cluster: #{cluster.inspect}" @@ -35,7 +29,7 @@ module GoogleApi # Responce exmaple # TODO: machine_type : Defailt 3.75 GB - def projects_zones_clusters_create(project_id, zone, cluster_name, cluster_size:, machine_type:) + def projects_zones_clusters_create(project_id, zone, cluster_name, cluster_size, machine_type:) service = Google::Apis::ContainerV1::ContainerService.new service.authorization = access_token @@ -50,8 +44,8 @@ module GoogleApi begin operation = service.create_cluster(project_id, zone, request_body) - rescue Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return nil + rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e + return e end puts "#{self.class.name} - #{__callee__}: operation: #{operation.inspect}" @@ -65,17 +59,15 @@ module GoogleApi begin operation = service.get_zone_operation(project_id, zone, operation_id) rescue Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return nil + return e end puts "#{self.class.name} - #{__callee__}: operation: #{operation.inspect}" operation end - def parse_self_link(self_link) - ret = self_link.match(/projects\/(.*)\/zones\/(.*)\/operations\/(.*)/) - - return ret[1], ret[2], ret[3] # project_id, zone, operation_id + def parse_operation_id(self_link) + self_link.match(/projects\/.*\/zones\/.*\/operations\/(.*)/)[1] end end end