Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-05-16 18:09:11 +00:00
parent d7b1354b39
commit 7ff36fc6e9
54 changed files with 120 additions and 1164 deletions

View File

@ -106,18 +106,8 @@ Dangerfile @gl-quality/eng-prod
/ee/spec/requests/projects/security/policies_controller_spec.rb @gitlab-org/protect/container-security-backend
/ee/app/models/security/orchestration_policy_configuration.rb @gitlab-org/protect/container-security-backend
/ee/spec/models/security/orchestration_policy_configuration_spec.rb @gitlab-org/protect/container-security-backend
/lib/gitlab/kubernetes/cilium_network_policy.rb @gitlab-org/protect/container-security-backend
/spec/lib/gitlab/kubernetes/cilium_network_policy_spec.rb @gitlab-org/protect/container-security-backend
/lib/gitlab/kubernetes/network_policy_common.rb @gitlab-org/protect/container-security-backend
/spec/support/shared_examples/lib/gitlab/kubernetes/network_policy_common_shared_examples.rb @gitlab-org/protect/container-security-backend
/lib/gitlab/kubernetes/network_policy.rb @gitlab-org/protect/container-security-backend
/spec/lib/gitlab/kubernetes/network_policy_spec.rb @gitlab-org/protect/container-security-backend
/ee/app/services/network_policies/** @gitlab-org/protect/container-security-backend
/ee/spec/services/network_policies/** @gitlab-org/protect/container-security-backend
/app/models/clusters/applications/cilium.rb @gitlab-org/protect/container-security-backend
/spec/models/clusters/applications/cilium_spec.rb @gitlab-org/protect/container-security-backend
/ee/app/services/network_policies/** @gitlab-org/protect/container-security-backend
/ee/spec/services/network_policies/** @gitlab-org/protect/container-security-backend
/ee/app/services/security/orchestration/** @gitlab-org/protect/container-security-backend
/ee/spec/services/security/orchestration/** @gitlab-org/protect/container-security-backend

View File

@ -1572,8 +1572,6 @@ Layout/LineLength:
- 'ee/app/services/merge_trains/refresh_merge_request_service.rb'
- 'ee/app/services/namespaces/check_excess_storage_size_service.rb'
- 'ee/app/services/namespaces/check_storage_size_service.rb'
- 'ee/app/services/network_policies/resources_service.rb'
- 'ee/app/services/network_policies/types.rb'
- 'ee/app/services/personal_access_tokens/rotation_verifier_service.rb'
- 'ee/app/services/projects/licenses/create_policy_service.rb'
- 'ee/app/services/projects/mark_for_deletion_service.rb'
@ -2942,10 +2940,6 @@ Layout/LineLength:
- 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb'
- 'ee/spec/services/merge_trains/refresh_service_spec.rb'
- 'ee/spec/services/namespaces/check_excess_storage_size_service_spec.rb'
- 'ee/spec/services/network_policies/delete_resource_service_spec.rb'
- 'ee/spec/services/network_policies/deploy_resource_service_spec.rb'
- 'ee/spec/services/network_policies/find_resource_service_spec.rb'
- 'ee/spec/services/network_policies/resources_service_spec.rb'
- 'ee/spec/services/personal_access_tokens/create_service_audit_log_spec.rb'
- 'ee/spec/services/personal_access_tokens/rotation_verifier_service_spec.rb'
- 'ee/spec/services/projects/alerting/notify_service_spec.rb'
@ -3082,7 +3076,6 @@ Layout/LineLength:
- 'ee/spec/support/shared_examples/services/geo/geo_request_service_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/group_saml/saml_provider/base_service_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/network_policies/kubeclient_error_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/scoped_label_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/search_notes_shared_examples.rb'
- 'ee/spec/support/shared_examples/services/sync_issue_and_requirement_state_shared_examples.rb'

View File

@ -107,7 +107,6 @@ RSpec/AnyInstanceOf:
- ee/spec/services/groups/destroy_service_spec.rb
- ee/spec/services/groups/update_service_spec.rb
- ee/spec/services/merge_trains/check_status_service_spec.rb
- ee/spec/services/network_policies/resources_service_spec.rb
- ee/spec/services/projects/destroy_service_spec.rb
- ee/spec/services/projects/group_links/destroy_service_spec.rb
- ee/spec/services/projects/update_service_spec.rb

View File

@ -194,10 +194,6 @@ RSpec/VerifiedDoubles:
- ee/spec/services/merge_requests/build_service_spec.rb
- ee/spec/services/merge_requests/reset_approvals_service_spec.rb
- ee/spec/services/namespaces/in_product_marketing_emails_service_spec.rb
- ee/spec/services/network_policies/delete_resource_service_spec.rb
- ee/spec/services/network_policies/deploy_resource_service_spec.rb
- ee/spec/services/network_policies/find_resource_service_spec.rb
- ee/spec/services/network_policies/resources_service_spec.rb
- ee/spec/services/projects/update_mirror_service_spec.rb
- ee/spec/services/projects/update_pages_service_spec.rb
- ee/spec/services/security/ingestion/ingest_report_slice_service_spec.rb

View File

@ -196,7 +196,7 @@ export default {
.then(
({ data: { httpIntegrationResetToken, prometheusIntegrationResetToken } = {} } = {}) => {
const [error] =
httpIntegrationResetToken?.errors || prometheusIntegrationResetToken?.errors;
httpIntegrationResetToken?.errors || prometheusIntegrationResetToken.errors;
if (error) {
return createFlash({ message: error });
}

View File

@ -135,7 +135,7 @@ export default {
variables,
})
.then(({ data }) => {
const { lists, hideBacklogList } = data[boardType]?.board;
const { lists, hideBacklogList } = data[boardType].board;
commit(types.RECEIVE_BOARD_LISTS_SUCCESS, formatBoardLists(lists));
// Backlog list needs to be created if it doesn't exist and it's not hidden
if (!lists.nodes.find((l) => l.listType === ListType.backlog) && !hideBacklogList) {
@ -430,7 +430,7 @@ export default {
variables,
})
.then(({ data }) => {
const { lists } = data[boardType]?.board;
const { lists } = data[boardType].board;
const listItems = formatListIssues(lists);
const listPageInfo = formatListsPageInfo(lists);
commit(types.RECEIVE_ITEMS_FOR_LIST_SUCCESS, { listItems, listPageInfo, listId });

View File

@ -26,7 +26,7 @@ export default Blockquote.extend({
const multilineInputRegex = /^\s*>>>\s$/gm;
return [
...this.parent?.(),
...this.parent(),
wrappingInputRule({
find: multilineInputRegex,
type: this.type,

View File

@ -30,7 +30,7 @@ export const getMarkdownSource = (element) => {
for (let i = range.start.row; i <= range.end.row; i += 1) {
if (i === range.start.row) {
elSource += source[i]?.substring(range.start.col);
elSource += source[i].substring(range.start.col);
} else if (i === range.end.row) {
elSource += `\n${source[i]?.substring(0, range.start.col)}`;
} else {

View File

@ -64,7 +64,7 @@ export class SourceEditorExtension {
const [start, end] =
bounds && Array.isArray(bounds)
? bounds
: window.location.hash?.replace(hashRegexp, '').split('-');
: window.location.hash.replace(hashRegexp, '').split('-');
let startLine = start ? parseInt(start, 10) : null;
let endLine = end ? parseInt(end, 10) : startLine;
if (endLine < startLine) {

View File

@ -170,7 +170,6 @@ export default class CreateMergeRequestDropdown {
createMergeRequest() {
return new Promise(() => {
this.isCreatingMergeRequest = true;
return this.createBranch().then(() => {
let path = canCreateConfidentialMergeRequest()
? this.createMrPath.replace(

View File

@ -56,7 +56,7 @@ export default {
});
},
runnerId() {
const { id, short_sha: token, description } = this.job?.runner;
const { id, short_sha: token, description } = this.job.runner;
return `#${id} (${token}) ${description}`;
},

View File

@ -12,7 +12,7 @@ import { isObject } from './type_utility';
import { getLocationHash } from './url_utility';
export const getPagePath = (index = 0) => {
const { page = '' } = document?.body?.dataset;
const { page = '' } = document.body.dataset;
return page.split(':')[index];
};
@ -105,7 +105,7 @@ export const handleLocationHash = () => {
}
if (isInIssuePage()) {
adjustment -= fixedIssuableTitle?.offsetHeight;
adjustment -= fixedIssuableTitle.offsetHeight;
}
if (isInMRPage()) {

View File

@ -42,7 +42,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
runnerHelpPagePath,
totalBranches,
ymlHelpPagePath,
} = el?.dataset;
} = el.dataset;
const configurationPaths = Object.fromEntries(
Object.entries(CODE_SNIPPET_SOURCE_SETTINGS).map(([source, { datasetKey }]) => [

View File

@ -313,7 +313,7 @@ export default {
errors = [],
warnings = [],
total_warnings: totalWarnings = 0,
} = err?.response?.data;
} = err.response.data;
const [error] = errors;
this.reportError({

View File

@ -17,7 +17,7 @@ export default () => {
fileParam,
settingsLink,
maxWarnings,
} = el?.dataset;
} = el.dataset;
const variableParams = JSON.parse(varParam);
const fileParams = JSON.parse(fileParam);

View File

@ -17,7 +17,7 @@ const createDagApp = (apolloProvider) => {
emptySvgPath,
pipelineProjectPath,
pipelineIid,
} = el?.dataset;
} = el.dataset;
// eslint-disable-next-line no-new
new Vue({

View File

@ -11,7 +11,7 @@ export const createPipelineHeaderApp = (elSelector, apolloProvider, graphqlResou
return;
}
const { fullPath, pipelineId, pipelineIid, pipelinesPath } = el?.dataset;
const { fullPath, pipelineId, pipelineIid, pipelinesPath } = el.dataset;
// eslint-disable-next-line no-new
new Vue({
el,

View File

@ -11,7 +11,7 @@ export const createPipelineNotificationApp = (elSelector, apolloProvider) => {
return;
}
const { deprecatedKeywordsDocPath, fullPath, pipelineIid } = el?.dataset;
const { deprecatedKeywordsDocPath, fullPath, pipelineIid } = el.dataset;
// eslint-disable-next-line no-new
new Vue({
el,

View File

@ -21,10 +21,10 @@ export default {
},
computed: {
prevPage() {
return this.pageInfo?.hasPreviousPage ? this.value?.page - 1 : null;
return this.pageInfo?.hasPreviousPage ? this.value.page - 1 : null;
},
nextPage() {
return this.pageInfo?.hasNextPage ? this.value?.page + 1 : null;
return this.pageInfo?.hasNextPage ? this.value.page + 1 : null;
},
},
methods: {

View File

@ -1,6 +1,6 @@
import { __ } from '~/locale';
export const DEBOUNCE_DELAY = 200;
export const DEBOUNCE_DELAY = 500;
export const MAX_RECENT_TOKENS_SIZE = 3;
export const FILTER_NONE = 'None';

View File

@ -286,6 +286,13 @@ class ApplicationController < ActionController::Base
end
end
def render_409(message = nil)
respond_to do |format|
format.html { render template: "errors/request_conflict", formats: :html, layout: "errors", status: :conflict, locals: { message: message } }
format.any { head :conflict }
end
end
def respond_422
head :unprocessable_entity
end

View File

@ -16,5 +16,6 @@ module Types
field :storage_size, GraphQL::Types::Float, null: false, description: 'Total storage in bytes.'
field :uploads_size, GraphQL::Types::Float, null: false, description: 'Uploads size in bytes.'
field :wiki_size, GraphQL::Types::Float, null: false, description: 'Wiki size in bytes.'
field :container_registry_size, GraphQL::Types::Float, null: false, description: 'Container Registry size in bytes.'
end
end

View File

@ -246,13 +246,13 @@ module MergeRequestsHelper
''
end
link_to branch, branch_path, class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-p-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n3'
link_to branch, branch_path, title: branch, class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-p-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n3'
end
def merge_request_header(project, merge_request)
link_to_author = link_to_member(project, merge_request.author, size: 24, extra_class: 'gl-font-weight-bold', avatar: false)
copy_button = clipboard_button(text: merge_request.source_branch, title: _('Copy branch name'), class: 'btn btn-default btn-sm gl-button btn-default-tertiary btn-icon gl-display-none! gl-md-display-inline-block! js-source-branch-copy')
target_branch = link_to merge_request.target_branch, project_tree_path(merge_request.target_project, merge_request.target_branch), class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-p-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n3'
target_branch = link_to merge_request.target_branch, project_tree_path(merge_request.target_project, merge_request.target_branch), title: merge_request.target_branch, class: 'gl-link gl-font-monospace gl-bg-blue-50 gl-rounded-base gl-font-sm gl-p-2 gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mb-n3'
_('%{author} requested to merge %{source_branch} %{copy_button} into %{target_branch} %{created_at}').html_safe % { author: link_to_author.html_safe, source_branch: merge_request_source_branch(merge_request).html_safe, copy_button: copy_button.html_safe, target_branch: target_branch.html_safe, created_at: time_ago_with_tooltip(merge_request.created_at, html_class: 'gl-display-inline-block').html_safe }
end

View File

@ -31,5 +31,3 @@ module Users
end
end
end
Users::GroupCalloutsHelper.prepend_mod

View File

@ -50,7 +50,8 @@ module Users
attention_requests_top_nav: 47,
attention_requests_side_nav: 48,
minute_limit_banner: 49,
preview_user_over_limit_free_plan_alert: 50 # EE-only
preview_user_over_limit_free_plan_alert: 50, # EE-only
user_reached_limit_free_plan_alert: 51 # EE-only
}
validates :feature_name,

View File

@ -0,0 +1,18 @@
- message = local_assigns.fetch(:message, nil)
- content_for(:title, 'Request Conflict')
%img{ :alt => "", :src => image_path('logo.svg') }
%h1
409
.container
%h2
= s_("409|There was a conflict with your request.")
- if message
%p
= message
%p
= s_('409|Please contact your GitLab administrator if you think this is a mistake.')
.action-container.js-go-back{ hidden: true }
%button{ type: 'button', class: 'gl-button btn btn-primary' }
= _('Go Back')
= render "errors/footer"

View File

@ -141,6 +141,9 @@ module Gitlab
Gitlab.ee { config.autoload_paths.push("#{config.root}/ee/lib/generators") }
Gitlab.jh { config.autoload_paths.push("#{config.root}/jh/lib/generators") }
# Add JH initializer into rails initializers path
Gitlab.jh { config.paths["config/initializers"] << "#{config.root}/jh/config/initializers" }
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
@ -501,21 +504,6 @@ module Gitlab
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.warn_on_new_connection = false
end
# Load JH initializers under JH. Load ordering is:
# 1. prepend_helpers_path
# 2. before_zeitwerk
# 3. let_zeitwerk_take_over
# 4. move_initializers
# 5. load_config_initializers
# 6. load_jh_config_initializers
Gitlab.jh do
initializer :load_jh_config_initializers, after: :load_config_initializers do
Dir[Rails.root.join('jh/config/initializers/*.rb')].sort.each do |initializer|
load_config_initializer(initializer)
end
end
end
# Add assets for variants of GitLab. They should take precedence over CE.
# This means if multiple files exist, e.g.:
#

View File

@ -16078,6 +16078,7 @@ Counts of requirements by their state.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="rootstoragestatisticsbuildartifactssize"></a>`buildArtifactsSize` | [`Float!`](#float) | CI artifacts size in bytes. |
| <a id="rootstoragestatisticscontainerregistrysize"></a>`containerRegistrySize` | [`Float!`](#float) | Container Registry size in bytes. |
| <a id="rootstoragestatisticsdependencyproxysize"></a>`dependencyProxySize` | [`Float!`](#float) | Dependency Proxy sizes in bytes. |
| <a id="rootstoragestatisticslfsobjectssize"></a>`lfsObjectsSize` | [`Float!`](#float) | LFS objects size in bytes. |
| <a id="rootstoragestatisticspackagessize"></a>`packagesSize` | [`Float!`](#float) | Packages size in bytes. |
@ -19416,6 +19417,7 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumtwo_factor_auth_recovery_settings_check"></a>`TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK` | Callout feature name for two_factor_auth_recovery_settings_check. |
| <a id="usercalloutfeaturenameenumultimate_trial"></a>`ULTIMATE_TRIAL` | Callout feature name for ultimate_trial. |
| <a id="usercalloutfeaturenameenumunfinished_tag_cleanup_callout"></a>`UNFINISHED_TAG_CLEANUP_CALLOUT` | Callout feature name for unfinished_tag_cleanup_callout. |
| <a id="usercalloutfeaturenameenumuser_reached_limit_free_plan_alert"></a>`USER_REACHED_LIMIT_FREE_PLAN_ALERT` | Callout feature name for user_reached_limit_free_plan_alert. |
| <a id="usercalloutfeaturenameenumverification_reminder"></a>`VERIFICATION_REMINDER` | Callout feature name for verification_reminder. |
| <a id="usercalloutfeaturenameenumweb_ide_alert_dismissed"></a>`WEB_IDE_ALERT_DISMISSED` | Callout feature name for web_ide_alert_dismissed. |
| <a id="usercalloutfeaturenameenumweb_ide_ci_environments_guidance"></a>`WEB_IDE_CI_ENVIRONMENTS_GUIDANCE` | Callout feature name for web_ide_ci_environments_guidance. |

View File

@ -853,7 +853,7 @@ A full list of variables can be found in [CI/CD variables](#available-cicd-varia
To find out what tools are pre-installed in the `license_scanning` Docker image use the following command:
```shell
$ docker run --entrypoint='' registry.gitlab.com/security-products/license-finder:3 /bin/bash -lc 'asdf list'
$ docker run --entrypoint='' registry.gitlab.com/security-products/license-finder:4 /bin/bash -lc 'asdf list'
golang
1.14
gradle
@ -880,7 +880,7 @@ sbt
To interact with the `license_scanning` runtime environment use the following command:
```shell
$ docker run -it --entrypoint='' registry.gitlab.com/security-products/license-finder:3 /bin/bash -l
$ docker run -it --entrypoint='' registry.gitlab.com/security-products/license-finder:4 /bin/bash -l
root@6abb70e9f193:~#
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -36,11 +36,14 @@ module Gitlab
private
def cleanup_gin_index(table_name)
sql = "select indexname::text from pg_indexes where tablename = '#{table_name}' and indexdef ilike '%gin%'"
sql = <<-SQL
SELECT indexname::text FROM pg_indexes WHERE tablename = '#{table_name}' AND indexdef ILIKE '%using gin%'
SQL
index_names = ApplicationRecord.connection.select_values(sql)
index_names.each do |index_name|
ApplicationRecord.connection.execute("select gin_clean_pending_list('#{index_name}')")
ApplicationRecord.connection.execute("SELECT gin_clean_pending_list('#{index_name}')")
end
end

View File

@ -14,7 +14,7 @@ variables:
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
LICENSE_MANAGEMENT_SETUP_CMD: '' # If needed, specify a command to setup your environment with a custom package manager.
LICENSE_MANAGEMENT_VERSION: 3
LICENSE_MANAGEMENT_VERSION: 4
license_scanning:
stage: test

View File

@ -1,141 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
class CiliumNetworkPolicy
include NetworkPolicyCommon
extend ::Gitlab::Utils::Override
API_VERSION = "cilium.io/v2"
KIND = 'CiliumNetworkPolicy'
PREDEFINED_POLICIES = {
'allow-inbound-http' => <<~YAML.rstrip,
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-inbound-http
spec:
endpointSelector:
matchLabels:
network-policy.gitlab.com/disabled_by: gitlab
ingress:
- toPorts:
- ports:
- port: '80'
- port: '443'
YAML
'drop-outbound' => <<~YAML.rstrip
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: drop-outbound
spec:
endpointSelector:
matchLabels:
network-policy.gitlab.com/disabled_by: gitlab
egress:
- {}
YAML
}.freeze
# We are modeling existing kubernetes resource and don't have
# control over amount of parameters.
# rubocop:disable Metrics/ParameterLists
def initialize(name:, namespace:, selector:, ingress:, resource_version: nil, description: nil, labels: nil, creation_timestamp: nil, egress: nil, annotations: nil, environment_ids: [])
@name = name
@description = description
@namespace = namespace
@labels = labels
@creation_timestamp = creation_timestamp
@selector = selector
@resource_version = resource_version
@ingress = ingress
@egress = egress
@annotations = annotations
@environment_ids = environment_ids
end
# rubocop:enable Metrics/ParameterLists
def self.from_yaml(manifest)
return unless manifest
policy = YAML.safe_load(manifest, symbolize_names: true)
return if !policy[:metadata] || !policy[:spec]
metadata = policy[:metadata]
spec = policy[:spec]
self.new(
name: metadata[:name],
description: policy[:description],
namespace: metadata[:namespace],
annotations: metadata[:annotations],
resource_version: metadata[:resourceVersion],
labels: metadata[:labels],
selector: spec[:endpointSelector],
ingress: spec[:ingress],
egress: spec[:egress]
)
rescue Psych::SyntaxError, Psych::DisallowedClass
nil
end
def self.from_resource(resource, environment_ids = [])
return unless resource
return if !resource[:metadata] || !resource[:spec]
metadata = resource[:metadata]
spec = resource[:spec].to_h
self.new(
name: metadata[:name],
description: resource[:description],
namespace: metadata[:namespace],
annotations: metadata[:annotations]&.to_h,
resource_version: metadata[:resourceVersion],
labels: metadata[:labels]&.to_h,
creation_timestamp: metadata[:creationTimestamp],
selector: spec[:endpointSelector],
ingress: spec[:ingress],
egress: spec[:egress],
environment_ids: environment_ids
)
end
override :resource
def resource
resource = {
apiVersion: API_VERSION,
kind: KIND,
metadata: metadata,
spec: spec
}
resource[:description] = description if description
resource
end
private
attr_reader :name, :description, :namespace, :labels, :creation_timestamp, :resource_version, :ingress, :egress, :annotations, :environment_ids
def selector
@selector ||= {}
end
def metadata
meta = { name: name, namespace: namespace }
meta[:labels] = labels if labels
meta[:resourceVersion] = resource_version if resource_version
meta[:annotations] = annotations if annotations
meta
end
def spec
{
endpointSelector: selector,
ingress: ingress,
egress: egress
}.compact
end
end
end
end

View File

@ -81,24 +81,6 @@ module Gitlab
:update_gateway,
to: :istio_client
# NetworkPolicy methods delegate to the apis/networking.k8s.io api
# group client
delegate :create_network_policy,
:get_network_policies,
:get_network_policy,
:update_network_policy,
:delete_network_policy,
to: :networking_client
# CiliumNetworkPolicy methods delegate to the apis/cilium.io api
# group client
delegate :create_cilium_network_policy,
:get_cilium_network_policies,
:get_cilium_network_policy,
:update_cilium_network_policy,
:delete_cilium_network_policy,
to: :cilium_networking_client
attr_reader :api_prefix, :kubeclient_options
DEFAULT_KUBECLIENT_OPTIONS = {

View File

@ -1,98 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
class NetworkPolicy
include NetworkPolicyCommon
extend ::Gitlab::Utils::Override
KIND = 'NetworkPolicy'
# rubocop:disable Metrics/ParameterLists
def initialize(name:, namespace:, selector:, ingress:, labels: nil, creation_timestamp: nil, policy_types: ["Ingress"], egress: nil, environment_ids: [])
@name = name
@namespace = namespace
@labels = labels
@creation_timestamp = creation_timestamp
@selector = selector
@policy_types = policy_types
@ingress = ingress
@egress = egress
@environment_ids = environment_ids
end
# rubocop:enable Metrics/ParameterLists
def self.from_yaml(manifest)
return unless manifest
policy = YAML.safe_load(manifest, symbolize_names: true)
return if !policy[:metadata] || !policy[:spec]
metadata = policy[:metadata]
spec = policy[:spec]
self.new(
name: metadata[:name],
namespace: metadata[:namespace],
labels: metadata[:labels],
selector: spec[:podSelector],
policy_types: spec[:policyTypes],
ingress: spec[:ingress],
egress: spec[:egress]
)
rescue Psych::SyntaxError, Psych::DisallowedClass
nil
end
def self.from_resource(resource, environment_ids = [])
return unless resource
return if !resource[:metadata] || !resource[:spec]
metadata = resource[:metadata]
spec = resource[:spec].to_h
self.new(
name: metadata[:name],
namespace: metadata[:namespace],
labels: metadata[:labels]&.to_h,
creation_timestamp: metadata[:creationTimestamp],
selector: spec[:podSelector],
policy_types: spec[:policyTypes],
ingress: spec[:ingress],
egress: spec[:egress],
environment_ids: environment_ids
)
end
override :resource
def resource
{
kind: KIND,
metadata: metadata,
spec: spec
}
end
private
attr_reader :name, :namespace, :labels, :creation_timestamp, :policy_types, :ingress, :egress, :environment_ids
def selector
@selector ||= {}
end
def metadata
meta = { name: name, namespace: namespace }
meta[:labels] = labels if labels
meta
end
def spec
{
podSelector: selector,
policyTypes: policy_types,
ingress: ingress,
egress: egress
}
end
end
end
end

View File

@ -1,63 +0,0 @@
# frozen_string_literal: true
module Gitlab
module Kubernetes
module NetworkPolicyCommon
DISABLED_BY_LABEL = :'network-policy.gitlab.com/disabled_by'
def generate
::Kubeclient::Resource.new(resource)
end
def as_json(opts = nil)
{
name: name,
namespace: namespace,
creation_timestamp: creation_timestamp,
manifest: manifest,
is_autodevops: autodevops?,
is_enabled: enabled?,
environment_ids: environment_ids
}
end
def autodevops?
return false unless labels
!labels[:chart].nil? && labels[:chart].start_with?('auto-deploy-app-')
end
# selector selects pods that should be targeted by this
# policy. It can represent podSelector, nodeSelector or
# endpointSelector We can narrow selection by requiring
# this policy to match our custom labels. Since DISABLED_BY
# label will not be on any pod a policy will be effectively disabled.
def enabled?
return true unless selector&.key?(:matchLabels)
!selector[:matchLabels]&.key?(DISABLED_BY_LABEL)
end
def enable
return if enabled?
selector[:matchLabels].delete(DISABLED_BY_LABEL)
end
def disable
selector[:matchLabels] ||= {}
selector[:matchLabels].merge!(DISABLED_BY_LABEL => 'gitlab')
end
private
def resource
raise NotImplementedError
end
def manifest
YAML.dump(resource.deep_stringify_keys)
end
end
end
end

View File

@ -79,7 +79,7 @@ module Gitlab
end
def self.renewal_service_email
'renewals-support@gitlab.com'
'renewals-service@customers.gitlab.com'
end
end
end

View File

@ -1473,7 +1473,7 @@ msgstr ""
msgid "1st contribution!"
msgstr ""
msgid "2. Before July 1, 2022, all free tier public open source projects will need to %{enrollment_link} to continue to receive GitLab Ultimate benefits."
msgid "2. Before July 1, 2022, all free tier public open source projects must %{enrollment_link} to continue to receive GitLab Ultimate benefits."
msgstr ""
msgid "20-29 contributions"
@ -1515,6 +1515,12 @@ msgstr ""
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
msgstr ""
msgid "409|Please contact your GitLab administrator if you think this is a mistake."
msgstr ""
msgid "409|There was a conflict with your request."
msgstr ""
msgid "7 days"
msgstr ""
@ -16180,6 +16186,9 @@ msgstr ""
msgid "For more information, go to the "
msgstr ""
msgid "For more information, see the %{faq_link}."
msgstr ""
msgid "For more information, see the File Hooks documentation."
msgstr ""
@ -16565,6 +16574,9 @@ msgstr ""
msgid "Geo|Filter by status"
msgstr ""
msgid "Geo|Full details"
msgstr ""
msgid "Geo|Geo Settings"
msgstr ""
@ -16682,9 +16694,6 @@ msgstr ""
msgid "Geo|Offline"
msgstr ""
msgid "Geo|Open replications"
msgstr ""
msgid "Geo|Pending synchronization"
msgstr ""
@ -25110,18 +25119,6 @@ msgstr ""
msgid "Network:"
msgstr ""
msgid "NetworkPolicies|Environment does not have deployment platform"
msgstr ""
msgid "NetworkPolicies|Invalid or empty policy"
msgstr ""
msgid "NetworkPolicies|Invalid or unsupported policy kind"
msgstr ""
msgid "NetworkPolicies|Kubernetes error: %{error}"
msgstr ""
msgid "NetworkPolicy|Policy"
msgstr ""
@ -28492,9 +28489,6 @@ msgstr ""
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
msgid "Please visit the %{faq_link} for more information."
msgstr ""
msgid "Please wait a moment, this page will automatically refresh when ready."
msgstr ""
@ -43160,6 +43154,9 @@ msgstr ""
msgid "You can group test cases using labels. To learn about the future direction of this feature, visit %{linkStart}Quality Management direction page%{linkEnd}."
msgstr ""
msgid "You can have a maximum of %{free_limit} unique members across all of your personal projects. To view and manage members, check the members page for each project in your namespace. We recommend you %{move_link_start}move your projects to a group%{move_link_end} so you can easily manage users and features."
msgstr ""
msgid "You can invite a new member to %{project_name} or invite another group."
msgstr ""
@ -43591,6 +43588,9 @@ msgstr ""
msgid "You've already enabled two-factor authentication using one time password authenticators. In order to register a different device, you must first disable two-factor authentication."
msgstr ""
msgid "You've reached your %{free_limit} member limit across all your personal projects"
msgstr ""
msgid "You've rejected %{user}"
msgstr ""

View File

@ -93,8 +93,13 @@ export default (
payload,
);
// eslint-disable-next-line no-restricted-syntax
return (result || new Promise((resolve) => setImmediate(resolve)))
return (
result ||
new Promise((resolve) => {
// eslint-disable-next-line no-restricted-syntax
setImmediate(resolve);
})
)
.catch((error) => {
validateResults();
throw error;

View File

@ -1 +1,4 @@
export default () => new Promise((resolve) => requestAnimationFrame(resolve));
export default () =>
new Promise((resolve) => {
requestAnimationFrame(resolve);
});

View File

@ -8,6 +8,7 @@ import {
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import ProjectSelect from '~/boards/components/project_select.vue';
import defaultState from '~/boards/stores/state';
@ -29,8 +30,6 @@ describe('ProjectSelect component', () => {
const findInMenuLoadingIcon = () => wrapper.find("[data-testid='dropdown-text-loading-icon']");
const findEmptySearchMessage = () => wrapper.find("[data-testid='empty-result-message']");
const waitRAF = () => new Promise((resolve) => requestAnimationFrame(resolve));
const createStore = ({ state, activeGroupProjects }) => {
Vue.use(Vuex);
@ -134,7 +133,7 @@ describe('ProjectSelect component', () => {
const dropdownToggle = findGlDropdown().find('.dropdown-toggle');
await dropdownToggle.trigger('click');
await waitRAF();
await waitForPromises();
await nextTick();
const searchInput = findGlDropdown().findComponent(GlFormInput).element;

View File

@ -70,7 +70,9 @@ describe('new dropdown upload', () => {
});
it('calls readAsText and creates file in plain text (without encoding) if the file content is plain text', async () => {
const waitForCreate = new Promise((resolve) => vm.$on('create', resolve));
const waitForCreate = new Promise((resolve) => {
vm.$on('create', resolve);
});
vm.createFile(textTarget, textFile);

View File

@ -254,7 +254,9 @@ describe('Actions Notes Store', () => {
jest.advanceTimersByTime(time);
}
return new Promise((resolve) => requestAnimationFrame(resolve));
return new Promise((resolve) => {
requestAnimationFrame(resolve);
});
};
const advanceXMoreIntervals = async (number) => {
const timeoutLength = pollInterval * number;

View File

@ -1,13 +1,5 @@
// Fixtures generated by: spec/frontend/fixtures/runner.rb
// List queries
import runnersData from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.json';
import runnersDataPaginated from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.paginated.json';
import runnersCountData from 'test_fixtures/graphql/runner/list/admin_runners_count.query.graphql.json';
import groupRunnersData from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.json';
import groupRunnersDataPaginated from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.paginated.json';
import groupRunnersCountData from 'test_fixtures/graphql/runner/list/group_runners_count.query.graphql.json';
// Show runner queries
import runnerData from 'test_fixtures/graphql/runner/show/runner.query.graphql.json';
import runnerWithGroupData from 'test_fixtures/graphql/runner/show/runner.query.graphql.with_group.json';
@ -17,6 +9,14 @@ import runnerJobsData from 'test_fixtures/graphql/runner/show/runner_jobs.query.
// Edit runner queries
import runnerFormData from 'test_fixtures/graphql/runner/edit/runner_form.query.graphql.json';
// List queries
import runnersData from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.json';
import runnersDataPaginated from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.paginated.json';
import runnersCountData from 'test_fixtures/graphql/runner/list/admin_runners_count.query.graphql.json';
import groupRunnersData from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.json';
import groupRunnersDataPaginated from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.paginated.json';
import groupRunnersCountData from 'test_fixtures/graphql/runner/list/group_runners_count.query.graphql.json';
// Other mock data
export const onlineContactTimeoutSecs = 2 * 60 * 60;
export const staleTimeoutSecs = 5259492; // Ruby's `2.months`

View File

@ -232,9 +232,7 @@ describe('FilteredSearchBarRoot', () => {
});
it('initializes `recentSearchesPromise` prop with a promise by using `recentSearchesService.fetch()`', () => {
jest
.spyOn(wrapper.vm.recentSearchesService, 'fetch')
.mockReturnValue(new Promise(() => []));
jest.spyOn(wrapper.vm.recentSearchesService, 'fetch').mockResolvedValue([]);
wrapper.vm.setupRecentSearch();

View File

@ -24,13 +24,19 @@ export const switchLeftSidebarTab = (name) => {
export const getStatusBar = () => document.querySelector('.ide-status-bar');
export const waitForMonacoEditor = () =>
new Promise((resolve) => monacoEditor.onDidCreateEditor(resolve));
new Promise((resolve) => {
monacoEditor.onDidCreateEditor(resolve);
});
export const waitForEditorDispose = (instance) =>
new Promise((resolve) => instance.onDidDispose(resolve));
new Promise((resolve) => {
instance.onDidDispose(resolve);
});
export const waitForEditorModelChange = (instance) =>
new Promise((resolve) => instance.onDidChangeModel(resolve));
new Promise((resolve) => {
instance.onDidChangeModel(resolve);
});
export const findMonacoEditor = () =>
screen.findAllByLabelText(/Editor content;/).then(([x]) => x.closest('.monaco-editor'));

View File

@ -8,7 +8,8 @@ RSpec.describe GitlabSchema.types['RootStorageStatistics'] do
it 'has all the required fields' do
expect(described_class).to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
:build_artifacts_size, :packages_size, :wiki_size, :snippets_size,
:pipeline_artifacts_size, :uploads_size, :dependency_proxy_size)
:pipeline_artifacts_size, :uploads_size, :dependency_proxy_size,
:container_registry_size)
end
specify { expect(described_class).to require_graphql_authorizations(:read_statistics) }

View File

@ -1,274 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Kubernetes::CiliumNetworkPolicy do
let(:policy) do
described_class.new(
name: name,
namespace: namespace,
description: description,
selector: selector,
ingress: ingress,
egress: egress,
labels: labels,
resource_version: resource_version,
annotations: annotations
)
end
let(:resource) do
::Kubeclient::Resource.new(
apiVersion: Gitlab::Kubernetes::CiliumNetworkPolicy::API_VERSION,
kind: Gitlab::Kubernetes::CiliumNetworkPolicy::KIND,
metadata: { name: name, namespace: namespace, resourceVersion: resource_version, annotations: annotations },
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: egress },
description: description
)
end
let(:selector) { endpoint_selector }
let(:labels) { nil }
let(:name) { 'example-name' }
let(:namespace) { 'example-namespace' }
let(:endpoint_selector) { { matchLabels: { role: 'db' } } }
let(:description) { 'example-description' }
let(:partial_class_name) { described_class.name.split('::').last }
let(:resource_version) { 101 }
let(:annotations) { { 'app.gitlab.com/alert': 'true' } }
let(:ingress) do
[
{
fromEndpoints: [
{ matchLabels: { project: 'myproject' } }
]
}
]
end
let(:egress) do
[
{
ports: [{ port: 5978 }]
}
]
end
include_examples 'network policy common specs'
describe '.from_yaml' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
description: example-description
metadata:
name: example-name
namespace: example-namespace
resourceVersion: 101
annotations:
app.gitlab.com/alert: "true"
spec:
endpointSelector:
matchLabels:
role: db
ingress:
- fromEndpoints:
- matchLabels:
project: myproject
egress:
- ports:
- port: 5978
POLICY
end
subject { Gitlab::Kubernetes::CiliumNetworkPolicy.from_yaml(manifest)&.generate }
it { is_expected.to eq(resource) }
context 'with nil manifest' do
let(:manifest) { nil }
it { is_expected.to be_nil }
end
context 'with invalid manifest' do
let(:manifest) { "\tfoo: bar" }
it { is_expected.to be_nil }
end
context 'with manifest without metadata' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
spec:
endpointSelector:
matchLabels:
role: db
ingress:
- fromEndpoints:
matchLabels:
project: myproject
POLICY
end
it { is_expected.to be_nil }
end
context 'with manifest without spec' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: example-name
namespace: example-namespace
POLICY
end
it { is_expected.to be_nil }
end
context 'with disallowed class' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: example-name
namespace: example-namespace
creationTimestamp: 2020-04-14T00:08:30Z
spec:
endpointSelector:
matchLabels:
role: db
ingress:
- fromEndpoints:
matchLabels:
project: myproject
POLICY
end
it { is_expected.to be_nil }
end
end
describe '.from_resource' do
let(:resource) do
::Kubeclient::Resource.new(
description: description,
metadata: {
name: name, namespace: namespace, creationTimestamp: '2020-04-14T00:08:30Z',
labels: { app: 'foo' }, resourceVersion: resource_version, annotations: annotations
},
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: nil, labels: nil }
)
end
let(:generated_resource) do
::Kubeclient::Resource.new(
apiVersion: Gitlab::Kubernetes::CiliumNetworkPolicy::API_VERSION,
kind: Gitlab::Kubernetes::CiliumNetworkPolicy::KIND,
description: description,
metadata: { name: name, namespace: namespace, resourceVersion: resource_version, labels: { app: 'foo' }, annotations: annotations },
spec: { endpointSelector: endpoint_selector, ingress: ingress }
)
end
subject { Gitlab::Kubernetes::CiliumNetworkPolicy.from_resource(resource)&.generate }
it { is_expected.to eq(generated_resource) }
context 'with nil resource' do
let(:resource) { nil }
it { is_expected.to be_nil }
end
context 'with resource without metadata' do
let(:resource) do
::Kubeclient::Resource.new(
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: nil, labels: nil }
)
end
it { is_expected.to be_nil }
end
context 'with resource without spec' do
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: name, namespace: namespace, uid: '128cf288-7de4-11ea-aceb-42010a800089', resourceVersion: resource_version }
)
end
it { is_expected.to be_nil }
end
context 'with environment_ids' do
subject { Gitlab::Kubernetes::CiliumNetworkPolicy.from_resource(resource, [1, 2, 3]) }
it 'includes environment_ids in as_json result' do
expect(subject.as_json).to include(environment_ids: [1, 2, 3])
end
end
end
describe '#resource' do
subject { policy.resource }
let(:resource) do
{
apiVersion: Gitlab::Kubernetes::CiliumNetworkPolicy::API_VERSION,
kind: Gitlab::Kubernetes::CiliumNetworkPolicy::KIND,
metadata: { name: name, namespace: namespace, resourceVersion: resource_version, annotations: annotations },
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: egress },
description: description
}
end
it { is_expected.to eq(resource) }
context 'with labels' do
let(:labels) { { app: 'foo' } }
before do
resource[:metadata][:labels] = { app: 'foo' }
end
it { is_expected.to eq(resource) }
end
context 'without resource_version' do
let(:resource_version) { nil }
before do
resource[:metadata].delete(:resourceVersion)
end
it { is_expected.to eq(resource) }
end
context 'with nil egress' do
let(:egress) { nil }
before do
resource[:spec].delete(:egress)
end
it { is_expected.to eq(resource) }
end
context 'without annotations' do
let(:annotations) { nil }
before do
resource[:metadata].delete(:annotations)
end
it { is_expected.to eq(resource) }
end
end
end

View File

@ -227,20 +227,6 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do
end
end
describe '#cilium_networking_client' do
subject { client.cilium_networking_client }
it_behaves_like 'a Kubeclient'
it 'has the cilium API group endpoint' do
expect(subject.api_endpoint.to_s).to match(%r{\/apis\/cilium.io\Z})
end
it 'has the api_version' do
expect(subject.instance_variable_get(:@api_version)).to eq('v2')
end
end
describe '#metrics_client' do
subject { client.metrics_client }
@ -428,56 +414,6 @@ RSpec.describe Gitlab::Kubernetes::KubeClient do
end
end
describe 'networking API group' do
let(:networking_client) { client.networking_client }
[
:create_network_policy,
:get_network_policies,
:get_network_policy,
:update_network_policy,
:delete_network_policy
].each do |method|
describe "##{method}" do
include_examples 'redirection not allowed', method
include_examples 'dns rebinding not allowed', method
it 'delegates to the networking client' do
expect(client).to delegate_method(method).to(:networking_client)
end
it 'responds to the method' do
expect(client).to respond_to method
end
end
end
end
describe 'cilium API group' do
let(:cilium_networking_client) { client.cilium_networking_client }
[
:create_cilium_network_policy,
:get_cilium_network_policies,
:get_cilium_network_policy,
:update_cilium_network_policy,
:delete_cilium_network_policy
].each do |method|
describe "##{method}" do
include_examples 'redirection not allowed', method
include_examples 'dns rebinding not allowed', method
it 'delegates to the cilium client' do
expect(client).to delegate_method(method).to(:cilium_networking_client)
end
it 'responds to the method' do
expect(client).to respond_to method
end
end
end
end
describe 'non-entity methods' do
it 'does not proxy for non-entity methods' do
expect(client).not_to respond_to :proxy_url

View File

@ -1,235 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Kubernetes::NetworkPolicy do
let(:policy) do
described_class.new(
name: name,
namespace: namespace,
selector: selector,
ingress: ingress,
labels: labels
)
end
let(:resource) do
::Kubeclient::Resource.new(
kind: Gitlab::Kubernetes::NetworkPolicy::KIND,
metadata: { name: name, namespace: namespace },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
let(:selector) { pod_selector }
let(:labels) { nil }
let(:name) { 'example-name' }
let(:namespace) { 'example-namespace' }
let(:pod_selector) { { matchLabels: { role: 'db' } } }
let(:ingress) do
[
{
from: [
{ namespaceSelector: { matchLabels: { project: 'myproject' } } }
]
}
]
end
let(:egress) do
[
{
ports: [{ port: 5978 }]
}
]
end
include_examples 'network policy common specs'
describe '.from_yaml' do
let(:manifest) do
<<~POLICY
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-name
namespace: example-namespace
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
POLICY
end
subject { Gitlab::Kubernetes::NetworkPolicy.from_yaml(manifest)&.generate }
it { is_expected.to eq(resource) }
context 'with nil manifest' do
let(:manifest) { nil }
it { is_expected.to be_nil }
end
context 'with invalid manifest' do
let(:manifest) { "\tfoo: bar" }
it { is_expected.to be_nil }
end
context 'with manifest without metadata' do
let(:manifest) do
<<~POLICY
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
POLICY
end
it { is_expected.to be_nil }
end
context 'with manifest without spec' do
let(:manifest) do
<<~POLICY
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-name
namespace: example-namespace
POLICY
end
it { is_expected.to be_nil }
end
context 'with disallowed class' do
let(:manifest) do
<<~POLICY
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-name
namespace: example-namespace
creationTimestamp: 2020-04-14T00:08:30Z
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
POLICY
end
it { is_expected.to be_nil }
end
end
describe '.from_resource' do
let(:resource) do
::Kubeclient::Resource.new(
metadata: {
name: name, namespace: namespace, creationTimestamp: '2020-04-14T00:08:30Z',
labels: { app: 'foo' }, resourceVersion: '4990'
},
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
let(:generated_resource) do
::Kubeclient::Resource.new(
kind: Gitlab::Kubernetes::NetworkPolicy::KIND,
metadata: { name: name, namespace: namespace, labels: { app: 'foo' } },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
subject { Gitlab::Kubernetes::NetworkPolicy.from_resource(resource)&.generate }
it { is_expected.to eq(generated_resource) }
context 'with nil resource' do
let(:resource) { nil }
it { is_expected.to be_nil }
end
context 'with resource without metadata' do
let(:resource) do
::Kubeclient::Resource.new(
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
it { is_expected.to be_nil }
end
context 'with resource without spec' do
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: name, namespace: namespace, uid: '128cf288-7de4-11ea-aceb-42010a800089', resourceVersion: '4990' }
)
end
it { is_expected.to be_nil }
end
context 'with environment_ids' do
subject { Gitlab::Kubernetes::NetworkPolicy.from_resource(resource, [1, 2, 3]) }
it 'includes environment_ids in as_json result' do
expect(subject.as_json).to include(environment_ids: [1, 2, 3])
end
end
end
describe '#resource' do
subject { policy.resource }
let(:resource) do
{
kind: Gitlab::Kubernetes::NetworkPolicy::KIND,
metadata: { name: name, namespace: namespace },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
}
end
it { is_expected.to eq(resource) }
context 'with labels' do
let(:labels) { { app: 'foo' } }
let(:resource) do
{
kind: Gitlab::Kubernetes::NetworkPolicy::KIND,
metadata: { name: name, namespace: namespace, labels: { app: 'foo' } },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
}
end
it { is_expected.to eq(resource) }
end
end
end

View File

@ -1,162 +0,0 @@
# frozen_string_literal: true
RSpec.shared_examples 'network policy common specs' do
let(:name) { 'example-name' }
let(:namespace) { 'example-namespace' }
let(:labels) { nil }
describe '#generate' do
subject { policy.generate }
it { is_expected.to eq(Kubeclient::Resource.new(policy.resource)) }
end
describe 'as_json' do
let(:json_policy) do
{
name: name,
namespace: namespace,
creation_timestamp: nil,
manifest: YAML.dump(policy.resource.deep_stringify_keys),
is_autodevops: false,
is_enabled: true,
environment_ids: []
}
end
subject { policy.as_json }
it { is_expected.to eq(json_policy) }
end
describe 'autodevops?' do
subject { policy.autodevops? }
let(:labels) { { chart: chart } }
let(:chart) { nil }
it { is_expected.to be false }
context 'with non-autodevops chart' do
let(:chart) { 'foo' }
it { is_expected.to be false }
end
context 'with autodevops chart' do
let(:chart) { 'auto-deploy-app-0.6.0' }
it { is_expected.to be true }
end
end
describe 'enabled?' do
subject { policy.enabled? }
let(:selector) { nil }
it { is_expected.to be true }
context 'with empty selector' do
let(:selector) { {} }
it { is_expected.to be true }
end
context 'with nil matchLabels in selector' do
let(:selector) { { matchLabels: nil } }
it { is_expected.to be true }
end
context 'with empty matchLabels in selector' do
let(:selector) { { matchLabels: {} } }
it { is_expected.to be true }
end
context 'with disabled_by label in matchLabels in selector' do
let(:selector) do
{ matchLabels: { Gitlab::Kubernetes::NetworkPolicyCommon::DISABLED_BY_LABEL => 'gitlab' } }
end
it { is_expected.to be false }
end
end
describe 'enable' do
subject { policy.enabled? }
let(:selector) { nil }
before do
policy.enable
end
it { is_expected.to be true }
context 'with empty selector' do
let(:selector) { {} }
it { is_expected.to be true }
end
context 'with nil matchLabels in selector' do
let(:selector) { { matchLabels: nil } }
it { is_expected.to be true }
end
context 'with empty matchLabels in selector' do
let(:selector) { { matchLabels: {} } }
it { is_expected.to be true }
end
context 'with disabled_by label in matchLabels in selector' do
let(:selector) do
{ matchLabels: { Gitlab::Kubernetes::NetworkPolicyCommon::DISABLED_BY_LABEL => 'gitlab' } }
end
it { is_expected.to be true }
end
end
describe 'disable' do
subject { policy.enabled? }
let(:selector) { nil }
before do
policy.disable
end
it { is_expected.to be false }
context 'with empty selector' do
let(:selector) { {} }
it { is_expected.to be false }
end
context 'with nil matchLabels in selector' do
let(:selector) { { matchLabels: nil } }
it { is_expected.to be false }
end
context 'with empty matchLabels in selector' do
let(:selector) { { matchLabels: {} } }
it { is_expected.to be false }
end
context 'with disabled_by label in matchLabels in selector' do
let(:selector) do
{ matchLabels: { Gitlab::Kubernetes::NetworkPolicyCommon::DISABLED_BY_LABEL => 'gitlab' } }
end
it { is_expected.to be false }
end
end
end