Skip to content
代码片段 群组 项目
未验证 提交 434e1eed 编辑于 作者: Hitesh Raghuvanshi's avatar Hitesh Raghuvanshi 提交者: GitLab
浏览文件

Merge branch 'gcp-integration-move-gcp-client-and-jwt-from-integrations-namespace' into 'master'

No related branches found
No related tags found
无相关合并请求
显示 178 个添加184 个删除
......@@ -16,7 +16,7 @@ def allowed?
end
def client
::Integrations::GoogleCloudPlatform::ArtifactRegistry::Client.new(
::GoogleCloudPlatform::ArtifactRegistry::Client.new(
project: project,
user: current_user,
gcp_project_id: gcp_project_id,
......
# frozen_string_literal: true
module GoogleCloudPlatform
module ArtifactRegistry
class Client < GoogleCloudPlatform::BaseClient
PAGE_SIZE = 10
def initialize(project:, user:, gcp_project_id:, gcp_location:, gcp_repository:, gcp_wlif:)
super(project: project, user: user)
@gcp_project_id = gcp_project_id
@gcp_location = gcp_location
@gcp_repository = gcp_repository
@gcp_wlif = gcp_wlif
end
def list_docker_images(page_token: nil)
url = list_docker_images_url
response = ::Gitlab::HTTP.get(
url,
headers: headers,
query: query_params(page_token: page_token),
format: :plain, # disable httparty json parsing
extra_allowed_uris: [URI(GLGO_BASE_URL)]
)
if response.success?
::Gitlab::Json.parse(response.body, symbolize_keys: true)
else
{}
end
end
private
def list_docker_images_url
"#{GLGO_BASE_URL}/gcp/ar/" \
"projects/#{@gcp_project_id}/" \
"locations/#{@gcp_location}/" \
"repositories/#{@gcp_repository}/docker"
end
def query_params(page_token: nil)
{
page_token: page_token,
page_size: PAGE_SIZE
}.compact
end
def headers
jwt = encoded_jwt(wlif: @gcp_wlif)
{
'Authorization' => "Bearer #{jwt}"
}
end
end
end
end
# frozen_string_literal: true
module GoogleCloudPlatform
class BaseClient
GLGO_BASE_URL = if Gitlab.staging?
'https://glgo.staging.runway.gitlab.net'
else
'https://glgo.runway.gitlab.net'
end
def initialize(project:, user:)
@project = project
@user = user
end
private
def encoded_jwt(wlif:)
jwt = ::GoogleCloudPlatform::Jwt.new(
project: @project,
user: @user,
claims: {
audience: GLGO_BASE_URL,
wlif: wlif
}
)
jwt.encoded
end
end
end
# frozen_string_literal: true
module GoogleCloudPlatform
class Jwt < ::JSONWebToken::RSAToken
extend ::Gitlab::Utils::Override
JWT_OPTIONS_ERROR = 'This jwt needs jwt claims audience and wlif to be set.'
NoSigningKeyError = Class.new(StandardError)
def initialize(project:, user:, claims:)
super
raise ArgumentError, JWT_OPTIONS_ERROR if claims[:audience].blank? || claims[:wlif].blank?
@claims = claims
@project = project
@user = user
end
def encoded
@custom_payload.merge!(custom_claims)
super
end
private
override :subject
def subject
"project_#{@project.id}_user_#{@user.id}"
end
override :key_data
def key_data
@key_data ||= begin
# TODO Feels strange to use the CI signing key but do
# we have a different signing key?
key_data = Gitlab::CurrentSettings.ci_jwt_signing_key
raise NoSigningKeyError unless key_data
key_data
end
end
def custom_claims
{
namespace_id: namespace.id.to_s,
namespace_path: namespace.full_path,
root_namespace_path: root_namespace.full_path,
root_namespace_id: root_namespace.id.to_s,
project_id: @project.id.to_s,
project_path: @project.full_path,
user_id: @user&.id.to_s,
user_login: @user&.username,
user_email: @user&.email,
wlif: @claims[:wlif]
}
end
def namespace
@project.namespace
end
def root_namespace
@project.root_namespace
end
override :issuer
def issuer
Feature.enabled?(:oidc_issuer_url) ? Gitlab.config.gitlab.url : Settings.gitlab.base_url
end
override :audience
def audience
@claims[:audience]
end
override :kid
def kid
rsa_key = OpenSSL::PKey::RSA.new(key_data)
rsa_key.public_key.to_jwk[:kid]
end
end
end
# frozen_string_literal: true
module Integrations
module GoogleCloudPlatform
module ArtifactRegistry
class Client < Integrations::GoogleCloudPlatform::BaseClient
PAGE_SIZE = 10
def initialize(project:, user:, gcp_project_id:, gcp_location:, gcp_repository:, gcp_wlif:)
super(project: project, user: user)
@gcp_project_id = gcp_project_id
@gcp_location = gcp_location
@gcp_repository = gcp_repository
@gcp_wlif = gcp_wlif
end
def list_docker_images(page_token: nil)
url = list_docker_images_url
response = ::Gitlab::HTTP.get(
url,
headers: headers,
query: query_params(page_token: page_token),
format: :plain, # disable httparty json parsing
extra_allowed_uris: [URI(GLGO_BASE_URL)]
)
if response.success?
::Gitlab::Json.parse(response.body, symbolize_keys: true)
else
{}
end
end
private
def list_docker_images_url
"#{GLGO_BASE_URL}/gcp/ar/" \
"projects/#{@gcp_project_id}/" \
"locations/#{@gcp_location}/" \
"repositories/#{@gcp_repository}/docker"
end
def query_params(page_token: nil)
{
page_token: page_token,
page_size: PAGE_SIZE
}.compact
end
def headers
jwt = encoded_jwt(wlif: @gcp_wlif)
{
'Authorization' => "Bearer #{jwt}"
}
end
end
end
end
end
# frozen_string_literal: true
module Integrations
module GoogleCloudPlatform
class BaseClient
GLGO_BASE_URL = if Gitlab.staging?
'https://glgo.staging.runway.gitlab.net'
else
'https://glgo.runway.gitlab.net'
end
def initialize(project:, user:)
@project = project
@user = user
end
private
def encoded_jwt(wlif:)
jwt = ::Integrations::GoogleCloudPlatform::Jwt.new(
project: @project,
user: @user,
claims: {
audience: GLGO_BASE_URL,
wlif: wlif
}
)
jwt.encoded
end
end
end
end
# frozen_string_literal: true
module Integrations
module GoogleCloudPlatform
class Jwt < ::JSONWebToken::RSAToken
extend ::Gitlab::Utils::Override
JWT_OPTIONS_ERROR = 'This jwt needs jwt claims audience and wlif to be set.'
NoSigningKeyError = Class.new(StandardError)
def initialize(project:, user:, claims:)
super
raise ArgumentError, JWT_OPTIONS_ERROR if claims[:audience].blank? || claims[:wlif].blank?
@claims = claims
@project = project
@user = user
end
def encoded
@custom_payload.merge!(custom_claims)
super
end
private
override :subject
def subject
"project_#{@project.id}_user_#{@user.id}"
end
override :key_data
def key_data
@key_data ||= begin
# TODO Feels strange to use the CI signing key but do
# we have a different signing key?
key_data = Gitlab::CurrentSettings.ci_jwt_signing_key
raise NoSigningKeyError unless key_data
key_data
end
end
def custom_claims
{
namespace_id: namespace.id.to_s,
namespace_path: namespace.full_path,
root_namespace_path: root_namespace.full_path,
root_namespace_id: root_namespace.id.to_s,
project_id: @project.id.to_s,
project_path: @project.full_path,
user_id: @user&.id.to_s,
user_login: @user&.username,
user_email: @user&.email,
wlif: @claims[:wlif]
}
end
def namespace
@project.namespace
end
def root_namespace
@project.root_namespace
end
override :issuer
def issuer
Feature.enabled?(:oidc_issuer_url) ? Gitlab.config.gitlab.url : Settings.gitlab.base_url
end
override :audience
def audience
@claims[:audience]
end
override :kid
def kid
rsa_key = OpenSSL::PKey::RSA.new(key_data)
rsa_key.public_key.to_jwk[:kid]
end
end
end
end
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Integrations::GoogleCloudPlatform::ArtifactRegistry::Client, feature_category: :container_registry do
RSpec.describe GoogleCloudPlatform::ArtifactRegistry::Client, feature_category: :container_registry do
let_it_be(:project) { create(:project) }
let_it_be(:rsa_key) { OpenSSL::PKey::RSA.generate(3072) }
let_it_be(:rsa_key_data) { rsa_key.to_s }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Integrations::GoogleCloudPlatform::Jwt, feature_category: :shared do
RSpec.describe GoogleCloudPlatform::Jwt, feature_category: :shared do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
......
......@@ -26,10 +26,10 @@
describe '#execute' do
let(:page_token) { nil }
let(:list_docker_images_response) { dummy_list_response }
let(:client_double) { instance_double('::Integrations::GoogleCloudPlatform::ArtifactRegistry::Client') }
let(:client_double) { instance_double('::GoogleCloudPlatform::ArtifactRegistry::Client') }
before do
allow(::Integrations::GoogleCloudPlatform::ArtifactRegistry::Client).to receive(:new)
allow(::GoogleCloudPlatform::ArtifactRegistry::Client).to receive(:new)
.with(
project: project,
user: user,
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册