diff options
23 files changed, 126 insertions, 30 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 5e3932db235..bee079c6643 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -54,10 +54,15 @@ const Api = { }); }, - groupMembers(id) { + groupMembers(id, options) { const url = Api.buildUrl(this.groupMembersPath).replace(':id', encodeURIComponent(id)); - return axios.get(url); + return axios.get(url, { + params: { + per_page: DEFAULT_PER_PAGE, + ...options, + }, + }); }, // Return groups list. Filtered by query diff --git a/app/services/clusters/kubernetes/create_or_update_namespace_service.rb b/app/services/clusters/kubernetes/create_or_update_namespace_service.rb index 15be8446cc0..c6c7eb99bf3 100644 --- a/app/services/clusters/kubernetes/create_or_update_namespace_service.rb +++ b/app/services/clusters/kubernetes/create_or_update_namespace_service.rb @@ -21,10 +21,15 @@ module Clusters attr_reader :cluster, :kubernetes_namespace, :platform def create_project_service_account + environment_slug = kubernetes_namespace.environment&.slug + namespace_labels = { 'app.gitlab.com/app' => kubernetes_namespace.project.full_path_slug } + namespace_labels['app.gitlab.com/env'] = environment_slug if environment_slug + Clusters::Kubernetes::CreateOrUpdateServiceAccountService.namespace_creator( platform.kubeclient, service_account_name: kubernetes_namespace.service_account_name, service_account_namespace: kubernetes_namespace.namespace, + service_account_namespace_labels: namespace_labels, rbac: platform.rbac? ).execute end diff --git a/app/services/clusters/kubernetes/create_or_update_service_account_service.rb b/app/services/clusters/kubernetes/create_or_update_service_account_service.rb index d798dcdcfd3..b1820474c9d 100644 --- a/app/services/clusters/kubernetes/create_or_update_service_account_service.rb +++ b/app/services/clusters/kubernetes/create_or_update_service_account_service.rb @@ -3,10 +3,11 @@ module Clusters module Kubernetes class CreateOrUpdateServiceAccountService - def initialize(kubeclient, service_account_name:, service_account_namespace:, token_name:, rbac:, namespace_creator: false, role_binding_name: nil) + def initialize(kubeclient, service_account_name:, service_account_namespace:, service_account_namespace_labels: nil, token_name:, rbac:, namespace_creator: false, role_binding_name: nil) @kubeclient = kubeclient @service_account_name = service_account_name @service_account_namespace = service_account_namespace + @service_account_namespace_labels = service_account_namespace_labels @token_name = token_name @rbac = rbac @namespace_creator = namespace_creator @@ -23,11 +24,12 @@ module Clusters ) end - def self.namespace_creator(kubeclient, service_account_name:, service_account_namespace:, rbac:) + def self.namespace_creator(kubeclient, service_account_name:, service_account_namespace:, service_account_namespace_labels:, rbac:) self.new( kubeclient, service_account_name: service_account_name, service_account_namespace: service_account_namespace, + service_account_namespace_labels: service_account_namespace_labels, token_name: "#{service_account_namespace}-token", rbac: rbac, namespace_creator: true, @@ -55,12 +57,13 @@ module Clusters private - attr_reader :kubeclient, :service_account_name, :service_account_namespace, :token_name, :rbac, :namespace_creator, :role_binding_name + attr_reader :kubeclient, :service_account_name, :service_account_namespace, :service_account_namespace_labels, :token_name, :rbac, :namespace_creator, :role_binding_name def ensure_project_namespace_exists Gitlab::Kubernetes::Namespace.new( service_account_namespace, - kubeclient + kubeclient, + labels: service_account_namespace_labels ).ensure_exists! end diff --git a/changelogs/unreleased/namespace-labels.yml b/changelogs/unreleased/namespace-labels.yml new file mode 100644 index 00000000000..231a7d63140 --- /dev/null +++ b/changelogs/unreleased/namespace-labels.yml @@ -0,0 +1,5 @@ +--- +title: Assign labels to the GMA and project k8s namespaces +merge_request: 23027 +author: +type: added diff --git a/doc/user/project/issues/design_management.md b/doc/user/project/issues/design_management.md index 83fbbd04739..496021c0a5b 100644 --- a/doc/user/project/issues/design_management.md +++ b/doc/user/project/issues/design_management.md @@ -86,6 +86,14 @@ to help summarize changes between versions. | Modified (in the selected version) | ![Design Modified](img/design_modified_v12_3.png) | | Added (in the selected version) | ![Design Added](img/design_added_v12_3.png) | +### Exploring designs by zooming + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13217) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.7. + +Designs can be explored in greater detail by zooming in and out of the image. Control the amount of zoom with the `+` and `-` buttons at the bottom of the image. While zoomed, you can still [add new annotations](#adding-annotations-to-designs) to the image, and see any existing ones. + +![Design zooming](img/design_zooming_v12_7.png) + ## Deleting designs > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11089) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4. diff --git a/doc/user/project/issues/img/design_zooming_v12_7.png b/doc/user/project/issues/img/design_zooming_v12_7.png Binary files differnew file mode 100644 index 00000000000..4acb4e10913 --- /dev/null +++ b/doc/user/project/issues/img/design_zooming_v12_7.png diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb index b5181670b93..c7c348ce9eb 100644 --- a/lib/gitlab/kubernetes/helm.rb +++ b/lib/gitlab/kubernetes/helm.rb @@ -6,6 +6,7 @@ module Gitlab HELM_VERSION = '2.16.1' KUBECTL_VERSION = '1.13.12' NAMESPACE = 'gitlab-managed-apps' + NAMESPACE_LABELS = { 'app.gitlab.com/managed_by' => :gitlab }.freeze SERVICE_ACCOUNT = 'tiller' CLUSTER_ROLE_BINDING = 'tiller-admin' CLUSTER_ROLE = 'cluster-admin' diff --git a/lib/gitlab/kubernetes/helm/api.rb b/lib/gitlab/kubernetes/helm/api.rb index 978cafae9ac..3ed07818302 100644 --- a/lib/gitlab/kubernetes/helm/api.rb +++ b/lib/gitlab/kubernetes/helm/api.rb @@ -6,7 +6,11 @@ module Gitlab class Api def initialize(kubeclient) @kubeclient = kubeclient - @namespace = Gitlab::Kubernetes::Namespace.new(Gitlab::Kubernetes::Helm::NAMESPACE, kubeclient) + @namespace = Gitlab::Kubernetes::Namespace.new( + Gitlab::Kubernetes::Helm::NAMESPACE, + kubeclient, + labels: Gitlab::Kubernetes::Helm::NAMESPACE_LABELS + ) end def install(command) diff --git a/lib/gitlab/kubernetes/namespace.rb b/lib/gitlab/kubernetes/namespace.rb index 8a3bea95a04..9862861118b 100644 --- a/lib/gitlab/kubernetes/namespace.rb +++ b/lib/gitlab/kubernetes/namespace.rb @@ -3,11 +3,12 @@ module Gitlab module Kubernetes class Namespace - attr_accessor :name + attr_accessor :name, :labels - def initialize(name, client) + def initialize(name, client, labels: nil) @name = name @client = client + @labels = labels end def exists? @@ -17,7 +18,7 @@ module Gitlab end def create! - resource = ::Kubeclient::Resource.new(metadata: { name: name }) + resource = ::Kubeclient::Resource.new(metadata: { name: name, labels: labels }) log_event(:begin_create) @client.create_namespace(resource) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index afe3abe3b89..e1770da3e99 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1754,6 +1754,9 @@ msgstr "" msgid "An error occurred while loading filenames" msgstr "" +msgid "An error occurred while loading group members." +msgstr "" + msgid "An error occurred while loading issues" msgstr "" @@ -9306,6 +9309,9 @@ msgstr "" msgid "GroupSAML|Generate a SCIM token to set up your System for Cross-Domain Identity Management." msgstr "" +msgid "GroupSAML|Identity" +msgstr "" + msgid "GroupSAML|Identity provider single sign on URL" msgstr "" @@ -9315,6 +9321,9 @@ msgstr "" msgid "GroupSAML|Manage your group’s membership while adding another level of security with SAML." msgstr "" +msgid "GroupSAML|Members" +msgstr "" + msgid "GroupSAML|Members will be forwarded here when signing in to your group. Get this from your identity provider, where it can also be called \"SSO Service Location\", \"SAML Token Issuance Endpoint\", or \"SAML 2.0/W-Federation URL\"." msgstr "" @@ -20152,6 +20161,9 @@ msgstr "" msgid "Used to help configure your identity provider" msgstr "" +msgid "User" +msgstr "" + msgid "User %{current_user_username} has started impersonating %{username}" msgstr "" diff --git a/spec/frontend/diffs/components/compare_versions_spec.js b/spec/frontend/diffs/components/compare_versions_spec.js index 7648c39976c..ff92a12eaf6 100644 --- a/spec/frontend/diffs/components/compare_versions_spec.js +++ b/spec/frontend/diffs/components/compare_versions_spec.js @@ -22,7 +22,6 @@ describe('CompareVersions', () => { store.state.diffs.diffFiles.push('test'); wrapper = mount(CompareVersionsComponent, { - attachToDocument: true, localVue, store, propsData: { diff --git a/spec/frontend/diffs/components/diff_file_header_spec.js b/spec/frontend/diffs/components/diff_file_header_spec.js index 19776b00194..e0b7e0bc0f3 100644 --- a/spec/frontend/diffs/components/diff_file_header_spec.js +++ b/spec/frontend/diffs/components/diff_file_header_spec.js @@ -91,7 +91,6 @@ describe('DiffFileHeader component', () => { }, localVue, store, - attachToDocument: true, }); }; diff --git a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js index 38bfa44e6d4..4d8345d494d 100644 --- a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js +++ b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js @@ -16,7 +16,6 @@ describe('DiffGutterAvatars', () => { propsData: { ...props, }, - attachToDocument: true, }); }; diff --git a/spec/frontend/diffs/components/edit_button_spec.js b/spec/frontend/diffs/components/edit_button_spec.js index ccab386169a..f9a1d4a84a8 100644 --- a/spec/frontend/diffs/components/edit_button_spec.js +++ b/spec/frontend/diffs/components/edit_button_spec.js @@ -9,7 +9,6 @@ describe('EditButton', () => { const createComponent = (props = {}) => { wrapper = shallowMount(EditButton, { propsData: { ...props }, - attachToDocument: true, }); }; diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js index 8f56b66350b..ceba31b1a70 100644 --- a/spec/frontend/notes/components/comment_form_spec.js +++ b/spec/frontend/notes/components/comment_form_spec.js @@ -37,7 +37,6 @@ describe('issue_comment_form component', () => { noteableType, }, store, - attachToDocument: true, }); }; diff --git a/spec/frontend/notes/components/discussion_jump_to_next_button_spec.js b/spec/frontend/notes/components/discussion_jump_to_next_button_spec.js index a2ef477b5d2..58cdf3cb57e 100644 --- a/spec/frontend/notes/components/discussion_jump_to_next_button_spec.js +++ b/spec/frontend/notes/components/discussion_jump_to_next_button_spec.js @@ -5,9 +5,7 @@ describe('JumpToNextDiscussionButton', () => { let wrapper; beforeEach(() => { - wrapper = shallowMount(JumpToNextDiscussionButton, { - attachToDocument: true, - }); + wrapper = shallowMount(JumpToNextDiscussionButton); }); afterEach(() => { diff --git a/spec/frontend/notes/components/discussion_notes_spec.js b/spec/frontend/notes/components/discussion_notes_spec.js index 1c004e5558e..81773752037 100644 --- a/spec/frontend/notes/components/discussion_notes_spec.js +++ b/spec/frontend/notes/components/discussion_notes_spec.js @@ -31,7 +31,6 @@ describe('DiscussionNotes', () => { slots: { 'avatar-badge': '<span class="avatar-badge-slot-content" />', }, - attachToDocument: true, }); }; diff --git a/spec/frontend/notes/components/note_app_spec.js b/spec/frontend/notes/components/note_app_spec.js index 76ed8134411..f9b69e72619 100644 --- a/spec/frontend/notes/components/note_app_spec.js +++ b/spec/frontend/notes/components/note_app_spec.js @@ -59,7 +59,6 @@ describe('note_app', () => { </div>`, }, { - attachToDocument: true, propsData, store, }, diff --git a/spec/frontend/notes/components/note_edited_text_spec.js b/spec/frontend/notes/components/note_edited_text_spec.js index 4671bc6629c..0a5fe48ef94 100644 --- a/spec/frontend/notes/components/note_edited_text_spec.js +++ b/spec/frontend/notes/components/note_edited_text_spec.js @@ -21,7 +21,6 @@ describe('NoteEditedText', () => { beforeEach(() => { wrapper = shallowMount(NoteEditedText, { propsData, - attachToDocument: true, }); }); diff --git a/spec/lib/gitlab/kubernetes/helm/api_spec.rb b/spec/lib/gitlab/kubernetes/helm/api_spec.rb index 5d9beec093a..e493acd7bad 100644 --- a/spec/lib/gitlab/kubernetes/helm/api_spec.rb +++ b/spec/lib/gitlab/kubernetes/helm/api_spec.rb @@ -6,7 +6,8 @@ describe Gitlab::Kubernetes::Helm::Api do let(:client) { double('kubernetes client') } let(:helm) { described_class.new(client) } let(:gitlab_namespace) { Gitlab::Kubernetes::Helm::NAMESPACE } - let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client) } + let(:gitlab_namespace_labels) { Gitlab::Kubernetes::Helm::NAMESPACE_LABELS } + let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client, labels: gitlab_namespace_labels) } let(:application_name) { 'app-name' } let(:rbac) { false } let(:files) { {} } @@ -23,13 +24,17 @@ describe Gitlab::Kubernetes::Helm::Api do subject { helm } before do - allow(Gitlab::Kubernetes::Namespace).to receive(:new).with(gitlab_namespace, client).and_return(namespace) + allow(Gitlab::Kubernetes::Namespace).to( + receive(:new).with(gitlab_namespace, client, labels: gitlab_namespace_labels).and_return(namespace) + ) allow(client).to receive(:create_config_map) end describe '#initialize' do it 'creates a namespace object' do - expect(Gitlab::Kubernetes::Namespace).to receive(:new).with(gitlab_namespace, client) + expect(Gitlab::Kubernetes::Namespace).to( + receive(:new).with(gitlab_namespace, client, labels: gitlab_namespace_labels) + ) subject end diff --git a/spec/lib/gitlab/kubernetes/namespace_spec.rb b/spec/lib/gitlab/kubernetes/namespace_spec.rb index 16634cc48e6..d44a803410f 100644 --- a/spec/lib/gitlab/kubernetes/namespace_spec.rb +++ b/spec/lib/gitlab/kubernetes/namespace_spec.rb @@ -5,8 +5,9 @@ require 'spec_helper' describe Gitlab::Kubernetes::Namespace do let(:name) { 'a_namespace' } let(:client) { double('kubernetes client') } + let(:labels) { nil } - subject { described_class.new(name, client) } + subject { described_class.new(name, client, labels: labels) } it { expect(subject.name).to eq(name) } @@ -49,6 +50,17 @@ describe Gitlab::Kubernetes::Namespace do expect { subject.create! }.not_to raise_error end + + context 'with labels' do + let(:labels) { { foo: :bar } } + + it 'creates a namespace with labels' do + matcher = have_attributes(metadata: have_attributes(name: name, labels: have_attributes(foo: :bar))) + expect(client).to receive(:create_namespace).with(matcher).once + + expect { subject.create! }.not_to raise_error + end + end end describe '#ensure_exists!' do diff --git a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb index bd1a90996a8..3982d2310d8 100644 --- a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb @@ -57,11 +57,21 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do end.to change(Clusters::KubernetesNamespace, :count).by(1) end - it 'creates project service account' do - expect_next_instance_of(Clusters::Kubernetes::CreateOrUpdateServiceAccountService) do |instance| - expect(instance).to receive(:execute).once - end - + it 'creates project service account and namespace' do + account_service = double(Clusters::Kubernetes::CreateOrUpdateServiceAccountService) + expect(Clusters::Kubernetes::CreateOrUpdateServiceAccountService).to( + receive(:namespace_creator).with( + cluster.platform.kubeclient, + service_account_name: "#{namespace}-service-account", + service_account_namespace: namespace, + service_account_namespace_labels: { + 'app.gitlab.com/app' => project.full_path_slug, + 'app.gitlab.com/env' => environment.slug + }, + rbac: true + ).and_return(account_service) + ) + expect(account_service).to receive(:execute).once subject end @@ -73,6 +83,29 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do expect(kubernetes_namespace.service_account_name).to eq("#{namespace}-service-account") expect(kubernetes_namespace.encrypted_service_account_token).to be_present end + + context 'without environment' do + before do + kubernetes_namespace.environment = nil + end + + it 'creates project service account and namespace' do + account_service = double(Clusters::Kubernetes::CreateOrUpdateServiceAccountService) + expect(Clusters::Kubernetes::CreateOrUpdateServiceAccountService).to( + receive(:namespace_creator).with( + cluster.platform.kubeclient, + service_account_name: "#{namespace}-service-account", + service_account_namespace: namespace, + service_account_namespace_labels: { + 'app.gitlab.com/app' => project.full_path_slug + }, + rbac: true + ).and_return(account_service) + ) + expect(account_service).to receive(:execute).once + subject + end + end end context 'group clusters' do diff --git a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb index 4df73fcc2ae..8fa22422074 100644 --- a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb @@ -116,6 +116,7 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do describe '.namespace_creator' do let(:namespace) { "#{project.path}-#{project.id}" } + let(:namespace_labels) { { app: project.full_path_slug, env: "staging" } } let(:service_account_name) { "#{namespace}-service-account" } let(:token_name) { "#{namespace}-token" } @@ -124,6 +125,7 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do kubeclient, service_account_name: service_account_name, service_account_namespace: namespace, + service_account_namespace_labels: namespace_labels, rbac: rbac ).execute end @@ -149,6 +151,16 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME, namespace: namespace) end + it 'creates a namespace object' do + kubernetes_namespace = double(Gitlab::Kubernetes::Namespace) + expect(Gitlab::Kubernetes::Namespace).to( + receive(:new).with(namespace, kubeclient, labels: namespace_labels).and_return(kubernetes_namespace) + ) + expect(kubernetes_namespace).to receive(:ensure_exists!) + + subject + end + it_behaves_like 'creates service account and token' it 'creates a namespaced role binding with edit access' do |