Commit 7e64b97a authored by Stan Hu's avatar Stan Hu

Merge branch 'incubation_5mp_google_cloud_backend_service_accounts' into 'master'

Service Accounts for `Project :: Google Cloud`

See merge request gitlab-org/gitlab!73895
parents 2a0626b5 0c119082
...@@ -6,14 +6,6 @@ const elementRenderer = (element, props = {}) => (createElement) => ...@@ -6,14 +6,6 @@ const elementRenderer = (element, props = {}) => (createElement) =>
export default () => { export default () => {
const root = document.querySelector('#js-google-cloud'); const root = document.querySelector('#js-google-cloud');
const props = JSON.parse(root.getAttribute('data'));
// uncomment this once backend is ready return new Vue({ el: root, render: elementRenderer(App, props) });
// const dataset = JSON.parse(root.getAttribute('data'));
const mockDataset = {
createServiceAccountUrl: '#create-url',
serviceAccounts: [],
emptyIllustrationUrl:
'https://gitlab.com/gitlab-org/gitlab-svgs/-/raw/main/illustrations/pipelines_empty.svg',
};
return new Vue({ el: root, render: elementRenderer(App, mockDataset) });
}; };
...@@ -8,6 +8,11 @@ class Projects::GoogleCloudController < Projects::ApplicationController ...@@ -8,6 +8,11 @@ class Projects::GoogleCloudController < Projects::ApplicationController
before_action :feature_flag_enabled? before_action :feature_flag_enabled?
def index def index
@js_data = {
serviceAccounts: GoogleCloud::ServiceAccountsService.new(project).find_for_project,
createServiceAccountUrl: '#mocked-url-create-service',
emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg')
}.to_json
end end
private private
......
# frozen_string_literal: true
module GoogleCloud
##
# GCP keys used to store Google Cloud Service Accounts
GCP_KEYS = %w[GCP_PROJECT_ID GCP_SERVICE_ACCOUNT GCP_SERVICE_ACCOUNT_KEY].freeze
##
# This service deals with GCP Service Accounts in GitLab
class ServiceAccountsService < ::BaseService
##
# Find GCP Service Accounts in a GitLab project
#
# This method looks up GitLab project's CI vars
# and returns Google Cloud Service Accounts combinations
# aligning GitLab project and environment to GCP projects
def find_for_project
group_vars_by_environment.map do |environment_scope, value|
{
environment: environment_scope,
gcp_project: value['GCP_PROJECT_ID'],
service_account_exists: value['GCP_SERVICE_ACCOUNT'].present?,
service_account_key_exists: value['GCP_SERVICE_ACCOUNT_KEY'].present?
}
end
end
private
def group_vars_by_environment
filtered_vars = @project.variables.filter { |variable| GCP_KEYS.include? variable.key }
filtered_vars.each_with_object({}) do |variable, grouped|
grouped[variable.environment_scope] ||= {}
grouped[variable.environment_scope][variable.key] = variable.value
end
end
end
end
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
- @content_class = "limit-container-width" unless fluid_layout - @content_class = "limit-container-width" unless fluid_layout
#js-google-cloud #js-google-cloud{ data: @js_data }
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GoogleCloud::ServiceAccountsService do
let_it_be(:project) { create(:project) }
let(:service) { described_class.new(project) }
describe 'find_for_project' do
context 'when a project does not have GCP service account vars' do
before do
project.variables.build(key: 'blah', value: 'foo', environment_scope: 'world')
project.save!
end
it 'returns an empty list' do
expect(service.find_for_project.length).to eq(0)
end
end
context 'when a project has GCP service account ci vars' do
before do
project.variables.build(environment_scope: '*', key: 'GCP_PROJECT_ID', value: 'prj1')
project.variables.build(environment_scope: '*', key: 'GCP_SERVICE_ACCOUNT_KEY', value: 'mock')
project.variables.build(environment_scope: 'staging', key: 'GCP_PROJECT_ID', value: 'prj2')
project.variables.build(environment_scope: 'staging', key: 'GCP_SERVICE_ACCOUNT', value: 'mock')
project.variables.build(environment_scope: 'production', key: 'GCP_PROJECT_ID', value: 'prj3')
project.variables.build(environment_scope: 'production', key: 'GCP_SERVICE_ACCOUNT', value: 'mock')
project.variables.build(environment_scope: 'production', key: 'GCP_SERVICE_ACCOUNT_KEY', value: 'mock')
project.save!
end
it 'returns a list of service accounts' do
list = service.find_for_project
aggregate_failures 'testing list of service accounts' do
expect(list.length).to eq(3)
expect(list.first[:environment]).to eq('*')
expect(list.first[:gcp_project]).to eq('prj1')
expect(list.first[:service_account_exists]).to eq(false)
expect(list.first[:service_account_key_exists]).to eq(true)
expect(list.second[:environment]).to eq('staging')
expect(list.second[:gcp_project]).to eq('prj2')
expect(list.second[:service_account_exists]).to eq(true)
expect(list.second[:service_account_key_exists]).to eq(false)
expect(list.third[:environment]).to eq('production')
expect(list.third[:gcp_project]).to eq('prj3')
expect(list.third[:service_account_exists]).to eq(true)
expect(list.third[:service_account_key_exists]).to eq(true)
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment