Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d10e04a10b
commit
015890a1b7
|
|
@ -1,28 +1,19 @@
|
|||
<script>
|
||||
/* eslint-disable vue/no-v-html */
|
||||
import { GlButton, GlIcon } from '@gitlab/ui';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import { GlButton, GlIcon, GlSprintf } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
|
||||
import notesEventHub from '../event_hub';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
information: s__(
|
||||
"Notes|You're only seeing %{boldStart}other activity%{boldEnd} in the feed. To add a comment, switch to one of the following options.",
|
||||
),
|
||||
},
|
||||
components: {
|
||||
GlButton,
|
||||
GlIcon,
|
||||
},
|
||||
computed: {
|
||||
timelineContent() {
|
||||
return sprintf(
|
||||
__(
|
||||
"You're only seeing %{startTag}other activity%{endTag} in the feed. To add a comment, switch to one of the following options.",
|
||||
),
|
||||
{
|
||||
startTag: `<b>`,
|
||||
endTag: `</b>`,
|
||||
},
|
||||
false,
|
||||
);
|
||||
},
|
||||
GlSprintf,
|
||||
},
|
||||
methods: {
|
||||
selectFilter(value) {
|
||||
|
|
@ -41,12 +32,18 @@ export default {
|
|||
<gl-icon name="comment" />
|
||||
</div>
|
||||
<div class="timeline-content">
|
||||
<div ref="timelineContent" v-html="timelineContent"></div>
|
||||
<div data-testid="discussion-filter-timeline-content">
|
||||
<gl-sprintf :message="$options.i18n.information">
|
||||
<template #bold="{ content }">
|
||||
<b>{{ content }}</b>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</div>
|
||||
<div class="discussion-filter-actions mt-2">
|
||||
<gl-button ref="showAllActivity" variant="default" @click="selectFilter(0)">
|
||||
<gl-button variant="default" @click="selectFilter(0)">
|
||||
{{ __('Show all activity') }}
|
||||
</gl-button>
|
||||
<gl-button ref="showComments" variant="default" @click="selectFilter(1)">
|
||||
<gl-button variant="default" @click="selectFilter(1)">
|
||||
{{ __('Show comments only') }}
|
||||
</gl-button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -25,12 +25,5 @@ module Types
|
|||
description: 'HTTP URL of the issues page, filtered by this release and `state=open`'
|
||||
field :closed_issues_url, GraphQL::STRING_TYPE, null: true,
|
||||
description: 'HTTP URL of the issues page, filtered by this release and `state=closed`'
|
||||
|
||||
field :merge_requests_url, GraphQL::STRING_TYPE, null: true, method: :opened_merge_requests_url,
|
||||
description: 'HTTP URL of the merge request page filtered by this release',
|
||||
deprecated: { reason: 'Use `openedMergeRequestsUrl`', milestone: '13.6' }
|
||||
field :issues_url, GraphQL::STRING_TYPE, null: true, method: :opened_issues_url,
|
||||
description: 'HTTP URL of the issues page filtered by this release',
|
||||
deprecated: { reason: 'Use `openedIssuesUrl`', milestone: '13.6' }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: 'certmanager',
|
||||
repository: repository,
|
||||
version: VERSION,
|
||||
|
|
@ -43,7 +43,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def uninstall_command
|
||||
Gitlab::Kubernetes::Helm::DeleteCommand.new(
|
||||
helm_command_module::DeleteCommand.new(
|
||||
name: 'certmanager',
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
files: files,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: 'crossplane',
|
||||
repository: repository,
|
||||
version: VERSION,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: 'elastic-stack',
|
||||
version: VERSION,
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
|
|
@ -39,7 +39,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def uninstall_command
|
||||
Gitlab::Kubernetes::Helm::DeleteCommand.new(
|
||||
helm_command_module::DeleteCommand.new(
|
||||
name: 'elastic-stack',
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
files: files,
|
||||
|
|
@ -96,7 +96,7 @@ module Clusters
|
|||
|
||||
def post_install_script
|
||||
[
|
||||
"timeout -t60 sh /data/helm/elastic-stack/config/wait-for-elasticsearch.sh http://elastic-stack-elasticsearch-master:9200"
|
||||
"timeout 60 sh /data/helm/elastic-stack/config/wait-for-elasticsearch.sh http://elastic-stack-elasticsearch-master:9200"
|
||||
]
|
||||
end
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ module Clusters
|
|||
# Chart version 3.0.0 moves to our own chart at https://gitlab.com/gitlab-org/charts/elastic-stack
|
||||
# and is not compatible with pre-existing resources. We first remove them.
|
||||
[
|
||||
Gitlab::Kubernetes::Helm::DeleteCommand.new(
|
||||
helm_command_module::DeleteCommand.new(
|
||||
name: 'elastic-stack',
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
files: files
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: 'fluentd',
|
||||
repository: repository,
|
||||
version: VERSION,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ require 'openssl'
|
|||
|
||||
module Clusters
|
||||
module Applications
|
||||
# DEPRECATED: This model represents the Helm 2 Tiller server, and is no longer being actively used.
|
||||
# It is being kept around for a potential cleanup of the unused Tiller server.
|
||||
class Helm < ApplicationRecord
|
||||
self.table_name = 'clusters_applications_helm'
|
||||
|
||||
|
|
@ -49,7 +51,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InitCommand.new(
|
||||
Gitlab::Kubernetes::Helm::V2::InitCommand.new(
|
||||
name: name,
|
||||
files: files,
|
||||
rbac: cluster.platform_kubernetes_rbac?
|
||||
|
|
@ -57,7 +59,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def uninstall_command
|
||||
Gitlab::Kubernetes::Helm::ResetCommand.new(
|
||||
Gitlab::Kubernetes::Helm::V2::ResetCommand.new(
|
||||
name: name,
|
||||
files: files,
|
||||
rbac: cluster.platform_kubernetes_rbac?
|
||||
|
|
@ -86,19 +88,19 @@ module Clusters
|
|||
end
|
||||
|
||||
def create_keys_and_certs
|
||||
ca_cert = Gitlab::Kubernetes::Helm::Certificate.generate_root
|
||||
ca_cert = Gitlab::Kubernetes::Helm::V2::Certificate.generate_root
|
||||
self.ca_key = ca_cert.key_string
|
||||
self.ca_cert = ca_cert.cert_string
|
||||
end
|
||||
|
||||
def tiller_cert
|
||||
@tiller_cert ||= ca_cert_obj.issue(expires_in: Gitlab::Kubernetes::Helm::Certificate::INFINITE_EXPIRY)
|
||||
@tiller_cert ||= ca_cert_obj.issue(expires_in: Gitlab::Kubernetes::Helm::V2::Certificate::INFINITE_EXPIRY)
|
||||
end
|
||||
|
||||
def ca_cert_obj
|
||||
return unless has_ssl?
|
||||
|
||||
Gitlab::Kubernetes::Helm::Certificate
|
||||
Gitlab::Kubernetes::Helm::V2::Certificate
|
||||
.from_strings(ca_key, ca_cert)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: name,
|
||||
repository: repository,
|
||||
version: VERSION,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: name,
|
||||
version: VERSION,
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: name,
|
||||
version: VERSION,
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
|
|
@ -94,7 +94,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def uninstall_command
|
||||
Gitlab::Kubernetes::Helm::DeleteCommand.new(
|
||||
helm_command_module::DeleteCommand.new(
|
||||
name: name,
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
files: files,
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: name,
|
||||
repository: repository,
|
||||
version: VERSION,
|
||||
|
|
@ -79,7 +79,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def patch_command(values)
|
||||
::Gitlab::Kubernetes::Helm::PatchCommand.new(
|
||||
helm_command_module::PatchCommand.new(
|
||||
name: name,
|
||||
repository: repository,
|
||||
version: version,
|
||||
|
|
@ -90,7 +90,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def uninstall_command
|
||||
Gitlab::Kubernetes::Helm::DeleteCommand.new(
|
||||
helm_command_module::DeleteCommand.new(
|
||||
name: name,
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
files: files,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ module Clusters
|
|||
end
|
||||
|
||||
def install_command
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
helm_command_module::InstallCommand.new(
|
||||
name: name,
|
||||
version: VERSION,
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
|
|
|
|||
|
|
@ -79,6 +79,9 @@ module Clusters
|
|||
validates :cluster_type, presence: true
|
||||
validates :domain, allow_blank: true, hostname: { allow_numeric_hostname: true }
|
||||
validates :namespace_per_environment, inclusion: { in: [true, false] }
|
||||
validates :helm_major_version, inclusion: { in: [2, 3] }
|
||||
|
||||
default_value_for :helm_major_version, 3
|
||||
|
||||
validate :restrict_modification, on: :update
|
||||
validate :no_groups, unless: :group_type?
|
||||
|
|
|
|||
|
|
@ -12,6 +12,17 @@ module Clusters
|
|||
|
||||
after_initialize :set_initial_status
|
||||
|
||||
def helm_command_module
|
||||
case cluster.helm_major_version
|
||||
when 3
|
||||
Gitlab::Kubernetes::Helm::V3
|
||||
when 2
|
||||
Gitlab::Kubernetes::Helm::V2
|
||||
else
|
||||
raise "Invalid Helm major version"
|
||||
end
|
||||
end
|
||||
|
||||
def set_initial_status
|
||||
return unless not_installable?
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module Clusters
|
|||
module Concerns
|
||||
module ApplicationData
|
||||
def uninstall_command
|
||||
Gitlab::Kubernetes::Helm::DeleteCommand.new(
|
||||
helm_command_module::DeleteCommand.new(
|
||||
name: name,
|
||||
rbac: cluster.platform_kubernetes_rbac?,
|
||||
files: files
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ class PagesDomain < ApplicationRecord
|
|||
return unless domain
|
||||
|
||||
if domain.downcase.ends_with?(Settings.pages.host.downcase)
|
||||
self.errors.add(:domain, "*.#{Settings.pages.host} is restricted")
|
||||
self.errors.add(:domain, "*.#{Settings.pages.host} is restricted. Please compare our documentation at https://docs.gitlab.com/ee/administration/pages/#advanced-configuration against your configuration.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replace v-html with GlSprintf in notes/.../discussion_filter_note.vue
|
||||
merge_request: 41482
|
||||
author: Takuya Noguchi
|
||||
type: other
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Use Helm 3 by default for GitLab-managed apps in new clusters
|
||||
merge_request: 46267
|
||||
author:
|
||||
type: changed
|
||||
|
|
@ -14,7 +14,6 @@ if Gitlab.ee? && Gitlab.dev_or_test_env?
|
|||
# being unique to licensed names. These feature flags should be reworked to
|
||||
# be "development" with explicit check
|
||||
IGNORED_FEATURE_FLAGS = %i[
|
||||
feature_flags_related_issues
|
||||
group_wikis
|
||||
swimlanes
|
||||
minimal_access_role
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class AddHelmMajorVersionToClusters < ActiveRecord::Migration[6.0]
|
||||
DOWNTIME = false
|
||||
|
||||
def change
|
||||
add_column(:clusters, :helm_major_version, :integer, default: 2, null: false)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
5520cca016af07fb2e009c0e3254362f106a9cc808cbb61e280221be82be1b25
|
||||
|
|
@ -10967,7 +10967,8 @@ CREATE TABLE clusters (
|
|||
namespace_per_environment boolean DEFAULT true NOT NULL,
|
||||
management_project_id integer,
|
||||
cleanup_status smallint DEFAULT 1 NOT NULL,
|
||||
cleanup_status_reason text
|
||||
cleanup_status_reason text,
|
||||
helm_major_version integer DEFAULT 2 NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE clusters_applications_cert_managers (
|
||||
|
|
|
|||
|
|
@ -17419,16 +17419,6 @@ type ReleaseLinks {
|
|||
"""
|
||||
editUrl: String
|
||||
|
||||
"""
|
||||
HTTP URL of the issues page filtered by this release. Deprecated in 13.6: Use `openedIssuesUrl`
|
||||
"""
|
||||
issuesUrl: String @deprecated(reason: "Use `openedIssuesUrl`. Deprecated in 13.6")
|
||||
|
||||
"""
|
||||
HTTP URL of the merge request page filtered by this release. Deprecated in 13.6: Use `openedMergeRequestsUrl`
|
||||
"""
|
||||
mergeRequestsUrl: String @deprecated(reason: "Use `openedMergeRequestsUrl`. Deprecated in 13.6")
|
||||
|
||||
"""
|
||||
HTTP URL of the merge request page , filtered by this release and `state=merged`
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -50230,34 +50230,6 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "issuesUrl",
|
||||
"description": "HTTP URL of the issues page filtered by this release. Deprecated in 13.6: Use `openedIssuesUrl`",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": true,
|
||||
"deprecationReason": "Use `openedIssuesUrl`. Deprecated in 13.6"
|
||||
},
|
||||
{
|
||||
"name": "mergeRequestsUrl",
|
||||
"description": "HTTP URL of the merge request page filtered by this release. Deprecated in 13.6: Use `openedMergeRequestsUrl`",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": true,
|
||||
"deprecationReason": "Use `openedMergeRequestsUrl`. Deprecated in 13.6"
|
||||
},
|
||||
{
|
||||
"name": "mergedMergeRequestsUrl",
|
||||
"description": "HTTP URL of the merge request page , filtered by this release and `state=merged`",
|
||||
|
|
|
|||
|
|
@ -2435,8 +2435,6 @@ Evidence for a release.
|
|||
| `closedIssuesUrl` | String | HTTP URL of the issues page, filtered by this release and `state=closed` |
|
||||
| `closedMergeRequestsUrl` | String | HTTP URL of the merge request page , filtered by this release and `state=closed` |
|
||||
| `editUrl` | String | HTTP URL of the release's edit page |
|
||||
| `issuesUrl` **{warning-solid}** | String | **Deprecated:** Use `openedIssuesUrl`. Deprecated in 13.6 |
|
||||
| `mergeRequestsUrl` **{warning-solid}** | String | **Deprecated:** Use `openedMergeRequestsUrl`. Deprecated in 13.6 |
|
||||
| `mergedMergeRequestsUrl` | String | HTTP URL of the merge request page , filtered by this release and `state=merged` |
|
||||
| `openedIssuesUrl` | String | HTTP URL of the issues page, filtered by this release and `state=open` |
|
||||
| `openedMergeRequestsUrl` | String | HTTP URL of the merge request page, filtered by this release and `state=open` |
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ module API
|
|||
expose :evidences, using: Entities::Releases::Evidence, expose_nil: false, if: ->(_, _) { can_download_code? }
|
||||
expose :_links do
|
||||
expose :self_url, as: :self, expose_nil: false
|
||||
expose :opened_merge_requests_url, as: :merge_requests_url, expose_nil: false
|
||||
expose :opened_issues_url, as: :issues_url, expose_nil: false
|
||||
expose :edit_url, expose_nil: false
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ module Gitlab
|
|||
validates :config, allowed_keys: ALLOWED_KEYS + PROCESSABLE_ALLOWED_KEYS
|
||||
|
||||
with_options allow_nil: true do
|
||||
validates :allow_failure, boolean: true
|
||||
validates :when, inclusion: {
|
||||
in: ALLOWED_WHEN,
|
||||
message: "should be one of: #{ALLOWED_WHEN.join(', ')}"
|
||||
|
|
@ -48,7 +47,7 @@ module Gitlab
|
|||
inherit: false,
|
||||
metadata: { allowed_needs: %i[job bridge] }
|
||||
|
||||
attributes :when, :allow_failure
|
||||
attributes :when
|
||||
|
||||
def self.matching?(name, config)
|
||||
!name.to_s.start_with?('.') &&
|
||||
|
|
@ -60,14 +59,6 @@ module Gitlab
|
|||
true
|
||||
end
|
||||
|
||||
def manual_action?
|
||||
self.when == 'manual'
|
||||
end
|
||||
|
||||
def ignored?
|
||||
allow_failure.nil? ? manual_action? : allow_failure
|
||||
end
|
||||
|
||||
def value
|
||||
super.merge(
|
||||
trigger: (trigger_value if trigger_defined?),
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ module Gitlab
|
|||
validates :script, presence: true
|
||||
|
||||
with_options allow_nil: true do
|
||||
validates :allow_failure, boolean: true
|
||||
validates :when, inclusion: {
|
||||
in: ALLOWED_WHEN,
|
||||
message: "should be one of: #{ALLOWED_WHEN.join(', ')}"
|
||||
|
|
@ -118,7 +117,7 @@ module Gitlab
|
|||
description: 'Parallel configuration for this job.',
|
||||
inherit: false
|
||||
|
||||
attributes :script, :tags, :allow_failure, :when, :dependencies,
|
||||
attributes :script, :tags, :when, :dependencies,
|
||||
:needs, :retry, :parallel, :start_in,
|
||||
:interruptible, :timeout, :resource_group, :release
|
||||
|
||||
|
|
@ -141,18 +140,10 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def manual_action?
|
||||
self.when == 'manual'
|
||||
end
|
||||
|
||||
def delayed?
|
||||
self.when == 'delayed'
|
||||
end
|
||||
|
||||
def ignored?
|
||||
allow_failure.nil? ? manual_action? : allow_failure
|
||||
end
|
||||
|
||||
def value
|
||||
super.merge(
|
||||
before_script: before_script_value,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ module Gitlab
|
|||
with_options allow_nil: true do
|
||||
validates :extends, array_of_strings_or_string: true
|
||||
validates :rules, array_of_hashes: true
|
||||
validates :allow_failure, boolean: true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -64,7 +65,7 @@ module Gitlab
|
|||
inherit: false,
|
||||
default: {}
|
||||
|
||||
attributes :extends, :rules
|
||||
attributes :extends, :rules, :allow_failure
|
||||
end
|
||||
|
||||
def compose!(deps = nil)
|
||||
|
|
@ -136,6 +137,14 @@ module Gitlab
|
|||
|
||||
root_variables.merge(variables_value.to_h)
|
||||
end
|
||||
|
||||
def manual_action?
|
||||
self.when == 'manual'
|
||||
end
|
||||
|
||||
def ignored?
|
||||
allow_failure.nil? ? manual_action? : allow_failure
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -55,9 +55,17 @@ module Gitlab
|
|||
end
|
||||
|
||||
def project_tree
|
||||
@project_tree ||= Gitlab::ImportExport::Project::TreeRestorer.new(user: current_user,
|
||||
shared: shared,
|
||||
project: project)
|
||||
@project_tree ||= project_tree_class.new(user: current_user,
|
||||
shared: shared,
|
||||
project: project)
|
||||
end
|
||||
|
||||
def project_tree_class
|
||||
sample_data_template? ? Gitlab::ImportExport::Project::Sample::TreeRestorer : Gitlab::ImportExport::Project::TreeRestorer
|
||||
end
|
||||
|
||||
def sample_data_template?
|
||||
project&.import_data&.data&.dig('sample_data')
|
||||
end
|
||||
|
||||
def avatar_restorer
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
module Project
|
||||
module Sample
|
||||
class RelationFactory < Project::RelationFactory
|
||||
DATE_MODELS = %i[issues milestones].freeze
|
||||
|
||||
def initialize(date_calculator:, **args)
|
||||
super(**args)
|
||||
|
||||
@date_calculator = date_calculator
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def setup_models
|
||||
super
|
||||
|
||||
# Override due date attributes in data hash for Sample Data templates
|
||||
# Dates are moved by taking the closest one to average and moving that (and rest around it) to the date of import
|
||||
override_date_attributes
|
||||
end
|
||||
|
||||
def override_date_attributes
|
||||
return unless DATE_MODELS.include?(@relation_name)
|
||||
|
||||
@relation_hash['start_date'] = calculate_by_closest_date(@relation_hash['start_date']&.to_time)
|
||||
@relation_hash['due_date'] = calculate_by_closest_date(@relation_hash['due_date']&.to_time)
|
||||
end
|
||||
|
||||
def calculate_by_closest_date(date)
|
||||
return unless date
|
||||
|
||||
@date_calculator.calculate_by_closest_date_to_average(date)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
module Project
|
||||
module Sample
|
||||
class RelationTreeRestorer < ImportExport::RelationTreeRestorer
|
||||
def initialize(*args)
|
||||
super
|
||||
|
||||
@date_calculator = Gitlab::ImportExport::Project::Sample::DateCalculator.new(dates)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def relation_factory_params(*args)
|
||||
super.merge(date_calculator: @date_calculator)
|
||||
end
|
||||
|
||||
def dates
|
||||
return [] if relation_reader.legacy?
|
||||
|
||||
RelationFactory::DATE_MODELS.flat_map do |tag|
|
||||
relation_reader.consume_relation(@importable_path, tag, mark_as_consumed: false).map do |model|
|
||||
model.first['due_date']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
module Project
|
||||
module Sample
|
||||
class SampleDataRelationTreeRestorer < RelationTreeRestorer
|
||||
DATE_MODELS = %i[issues milestones].freeze
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
|
||||
date_calculator
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_relation(relation_key, relation_definition, data_hash)
|
||||
# Override due date attributes in data hash for Sample Data templates
|
||||
# Dates are moved by taking the closest one to average and moving that (and rest around it) to the date of import
|
||||
# TODO: To move this logic to RelationFactory (see: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41699#note_430465333)
|
||||
override_date_attributes!(relation_key, data_hash)
|
||||
super
|
||||
end
|
||||
|
||||
def override_date_attributes!(relation_key, data_hash)
|
||||
return unless DATE_MODELS.include?(relation_key.to_sym)
|
||||
|
||||
data_hash['start_date'] = date_calculator.calculate_by_closest_date_to_average(data_hash['start_date'].to_time) unless data_hash['start_date'].nil?
|
||||
data_hash['due_date'] = date_calculator.calculate_by_closest_date_to_average(data_hash['due_date'].to_time) unless data_hash['due_date'].nil?
|
||||
end
|
||||
|
||||
def dates
|
||||
return if relation_reader.legacy?
|
||||
|
||||
DATE_MODELS.flat_map do |tag|
|
||||
relation_reader.consume_relation(@importable_path, tag, mark_as_consumed: false).map do |model|
|
||||
model.first['due_date']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def date_calculator
|
||||
@date_calculator ||= Gitlab::ImportExport::Project::Sample::DateCalculator.new(dates)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
module Project
|
||||
module Sample
|
||||
class TreeRestorer < Project::TreeRestorer
|
||||
def relation_tree_restorer_class
|
||||
RelationTreeRestorer
|
||||
end
|
||||
|
||||
def relation_factory
|
||||
RelationFactory
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -85,11 +85,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def relation_tree_restorer_class
|
||||
sample_data_template? ? Sample::SampleDataRelationTreeRestorer : RelationTreeRestorer
|
||||
end
|
||||
|
||||
def sample_data_template?
|
||||
@project&.import_data&.data&.dig('sample_data')
|
||||
RelationTreeRestorer
|
||||
end
|
||||
|
||||
def members_mapper
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class BaseCommand
|
||||
attr_reader :name, :files
|
||||
|
||||
def initialize(rbac:, name:, files:)
|
||||
@rbac = rbac
|
||||
@name = name
|
||||
@files = files
|
||||
end
|
||||
|
||||
def rbac?
|
||||
@rbac
|
||||
end
|
||||
|
||||
def pod_resource
|
||||
pod_service_account_name = rbac? ? service_account_name : nil
|
||||
|
||||
Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
|
||||
end
|
||||
|
||||
def generate_script
|
||||
<<~HEREDOC
|
||||
set -xeo pipefail
|
||||
HEREDOC
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"install-#{name}"
|
||||
end
|
||||
|
||||
def config_map_resource
|
||||
Gitlab::Kubernetes::ConfigMap.new(name, files).generate
|
||||
end
|
||||
|
||||
def service_account_resource
|
||||
return unless rbac?
|
||||
|
||||
Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
|
||||
end
|
||||
|
||||
def cluster_role_binding_resource
|
||||
return unless rbac?
|
||||
|
||||
subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
|
||||
|
||||
Gitlab::Kubernetes::ClusterRoleBinding.new(
|
||||
cluster_role_binding_name,
|
||||
cluster_role_name,
|
||||
subjects
|
||||
).generate
|
||||
end
|
||||
|
||||
def file_names
|
||||
files.keys
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def files_dir
|
||||
"/data/helm/#{name}/config"
|
||||
end
|
||||
|
||||
def namespace
|
||||
Gitlab::Kubernetes::Helm::NAMESPACE
|
||||
end
|
||||
|
||||
def service_account_name
|
||||
Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
|
||||
end
|
||||
|
||||
def cluster_role_binding_name
|
||||
Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
|
||||
end
|
||||
|
||||
def cluster_role_name
|
||||
Gitlab::Kubernetes::Helm::CLUSTER_ROLE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class Certificate
|
||||
INFINITE_EXPIRY = 1000.years
|
||||
SHORT_EXPIRY = 30.minutes
|
||||
|
||||
attr_reader :key, :cert
|
||||
|
||||
def key_string
|
||||
@key.to_s
|
||||
end
|
||||
|
||||
def cert_string
|
||||
@cert.to_pem
|
||||
end
|
||||
|
||||
def self.from_strings(key_string, cert_string)
|
||||
key = OpenSSL::PKey::RSA.new(key_string)
|
||||
cert = OpenSSL::X509::Certificate.new(cert_string)
|
||||
new(key, cert)
|
||||
end
|
||||
|
||||
def self.generate_root
|
||||
_issue(signed_by: nil, expires_in: INFINITE_EXPIRY, certificate_authority: true)
|
||||
end
|
||||
|
||||
def issue(expires_in: SHORT_EXPIRY)
|
||||
self.class._issue(signed_by: self, expires_in: expires_in, certificate_authority: false)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self._issue(signed_by:, expires_in:, certificate_authority:)
|
||||
key = OpenSSL::PKey::RSA.new(4096)
|
||||
public_key = key.public_key
|
||||
|
||||
subject = OpenSSL::X509::Name.parse("/C=US")
|
||||
|
||||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.subject = subject
|
||||
|
||||
cert.issuer = signed_by&.cert&.subject || subject
|
||||
|
||||
cert.not_before = Time.now
|
||||
cert.not_after = expires_in.from_now
|
||||
cert.public_key = public_key
|
||||
cert.serial = 0x0
|
||||
cert.version = 2
|
||||
|
||||
if certificate_authority
|
||||
extension_factory = OpenSSL::X509::ExtensionFactory.new
|
||||
extension_factory.subject_certificate = cert
|
||||
extension_factory.issuer_certificate = cert
|
||||
cert.add_extension(extension_factory.create_extension('subjectKeyIdentifier', 'hash'))
|
||||
cert.add_extension(extension_factory.create_extension('basicConstraints', 'CA:TRUE', true))
|
||||
cert.add_extension(extension_factory.create_extension('keyUsage', 'cRLSign,keyCertSign', true))
|
||||
end
|
||||
|
||||
cert.sign(signed_by&.key || key, OpenSSL::Digest::SHA256.new)
|
||||
|
||||
new(key, cert)
|
||||
end
|
||||
|
||||
def initialize(key, cert)
|
||||
@key = key
|
||||
@cert = cert
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module ClientCommand
|
||||
def init_command
|
||||
<<~SHELL.chomp
|
||||
export HELM_HOST="localhost:44134"
|
||||
tiller -listen ${HELM_HOST} -alsologtostderr &
|
||||
helm init --client-only
|
||||
SHELL
|
||||
end
|
||||
|
||||
def repository_command
|
||||
['helm', 'repo', 'add', name, repository].shelljoin if repository
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def repository_update_command
|
||||
'helm repo update'
|
||||
end
|
||||
|
||||
def optional_tls_flags
|
||||
return [] unless files.key?(:'ca.pem')
|
||||
|
||||
[
|
||||
'--tls',
|
||||
'--tls-ca-cert', "#{files_dir}/ca.pem",
|
||||
'--tls-cert', "#{files_dir}/cert.pem",
|
||||
'--tls-key', "#{files_dir}/key.pem"
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class DeleteCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
attr_reader :predelete, :postdelete
|
||||
|
||||
def initialize(predelete: nil, postdelete: nil, **args)
|
||||
super(**args)
|
||||
@predelete = predelete
|
||||
@postdelete = postdelete
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
init_command,
|
||||
predelete,
|
||||
delete_command,
|
||||
postdelete
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"uninstall-#{name}"
|
||||
end
|
||||
|
||||
def delete_command
|
||||
['helm', 'delete', '--purge', name].shelljoin
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class InitCommand < BaseCommand
|
||||
def generate_script
|
||||
super + [
|
||||
init_helm_command
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_helm_command
|
||||
command = %w[helm init] + init_command_flags
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def init_command_flags
|
||||
tls_flags + optional_service_account_flag
|
||||
end
|
||||
|
||||
def tls_flags
|
||||
[
|
||||
'--tiller-tls',
|
||||
'--tiller-tls-verify',
|
||||
'--tls-ca-cert', "#{files_dir}/ca.pem",
|
||||
'--tiller-tls-cert', "#{files_dir}/cert.pem",
|
||||
'--tiller-tls-key', "#{files_dir}/key.pem"
|
||||
]
|
||||
end
|
||||
|
||||
def optional_service_account_flag
|
||||
return [] unless rbac?
|
||||
|
||||
['--service-account', service_account_name]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class InstallCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
attr_reader :chart, :repository, :preinstall, :postinstall
|
||||
attr_accessor :version
|
||||
|
||||
def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
|
||||
super(**args)
|
||||
@chart = chart
|
||||
@version = version
|
||||
@repository = repository
|
||||
@preinstall = preinstall
|
||||
@postinstall = postinstall
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
init_command,
|
||||
repository_command,
|
||||
repository_update_command,
|
||||
preinstall,
|
||||
install_command,
|
||||
postinstall
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Uses `helm upgrade --install` which means we can use this for both
|
||||
# installation and uprade of applications
|
||||
def install_command
|
||||
command = ['helm', 'upgrade', name, chart] +
|
||||
install_flag +
|
||||
rollback_support_flag +
|
||||
reset_values_flag +
|
||||
optional_version_flag +
|
||||
rbac_create_flag +
|
||||
namespace_flag +
|
||||
value_flag
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def install_flag
|
||||
['--install']
|
||||
end
|
||||
|
||||
def reset_values_flag
|
||||
['--reset-values']
|
||||
end
|
||||
|
||||
def value_flag
|
||||
['-f', "/data/helm/#{name}/config/values.yaml"]
|
||||
end
|
||||
|
||||
def namespace_flag
|
||||
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
|
||||
end
|
||||
|
||||
def rbac_create_flag
|
||||
if rbac?
|
||||
%w[--set rbac.create=true,rbac.enabled=true]
|
||||
else
|
||||
%w[--set rbac.create=false,rbac.enabled=false]
|
||||
end
|
||||
end
|
||||
|
||||
def optional_version_flag
|
||||
return [] unless version
|
||||
|
||||
['--version', version]
|
||||
end
|
||||
|
||||
def rollback_support_flag
|
||||
['--atomic', '--cleanup-on-fail']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# PatchCommand is for updating values in installed charts without overwriting
|
||||
# existing values.
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class PatchCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
attr_reader :chart, :repository
|
||||
attr_accessor :version
|
||||
|
||||
def initialize(chart:, version:, repository: nil, **args)
|
||||
super(**args)
|
||||
|
||||
# version is mandatory to prevent chart mismatches
|
||||
# we do not want our values interpreted in the context of the wrong version
|
||||
raise ArgumentError, 'version is required' if version.blank?
|
||||
|
||||
@chart = chart
|
||||
@version = version
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
init_command,
|
||||
repository_command,
|
||||
repository_update_command,
|
||||
upgrade_command
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def upgrade_command
|
||||
command = ['helm', 'upgrade', name, chart] +
|
||||
reuse_values_flag +
|
||||
version_flag +
|
||||
namespace_flag +
|
||||
value_flag
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def reuse_values_flag
|
||||
['--reuse-values']
|
||||
end
|
||||
|
||||
def value_flag
|
||||
['-f', "/data/helm/#{name}/config/values.yaml"]
|
||||
end
|
||||
|
||||
def namespace_flag
|
||||
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
|
||||
end
|
||||
|
||||
def version_flag
|
||||
['--version', version]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -27,7 +27,7 @@ module Gitlab
|
|||
def container_specification
|
||||
{
|
||||
name: 'helm',
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/#{Gitlab::Kubernetes::Helm::HELM_VERSION}-kube-#{Gitlab::Kubernetes::Helm::KUBECTL_VERSION}",
|
||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/#{command.class::HELM_VERSION}-kube-#{Gitlab::Kubernetes::Helm::KUBECTL_VERSION}-alpine-3.12",
|
||||
env: generate_pod_env(command),
|
||||
command: %w(/bin/sh),
|
||||
args: %w(-c $(COMMAND_SCRIPT))
|
||||
|
|
@ -50,11 +50,10 @@ module Gitlab
|
|||
end
|
||||
|
||||
def generate_pod_env(command)
|
||||
{
|
||||
HELM_VERSION: Gitlab::Kubernetes::Helm::HELM_VERSION,
|
||||
TILLER_NAMESPACE: namespace_name,
|
||||
command.env.merge(
|
||||
HELM_VERSION: command.class::HELM_VERSION,
|
||||
COMMAND_SCRIPT: command.generate_script
|
||||
}.map { |key, value| { name: key, value: value } }
|
||||
).map { |key, value| { name: key, value: value } }
|
||||
end
|
||||
|
||||
def volumes_specification
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
class ResetCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
reset_helm_command,
|
||||
delete_tiller_replicaset,
|
||||
delete_tiller_clusterrolebinding
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"uninstall-#{name}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# This method can be delete once we upgrade Helm to > 12.13.0
|
||||
# https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/27096#note_159695900
|
||||
#
|
||||
# Tracking this method to be removed here:
|
||||
# https://gitlab.com/gitlab-org/gitlab-foss/issues/52791#note_199374155
|
||||
def delete_tiller_replicaset
|
||||
delete_args = %w[replicaset -n gitlab-managed-apps -l name=tiller]
|
||||
|
||||
Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
|
||||
end
|
||||
|
||||
def delete_tiller_clusterrolebinding
|
||||
delete_args = %w[clusterrolebinding tiller-admin]
|
||||
|
||||
Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
|
||||
end
|
||||
|
||||
def reset_helm_command
|
||||
command = %w[helm reset] + optional_tls_flags
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
class BaseCommand
|
||||
attr_reader :name, :files
|
||||
|
||||
HELM_VERSION = '2.16.9'
|
||||
|
||||
def initialize(rbac:, name:, files:)
|
||||
@rbac = rbac
|
||||
@name = name
|
||||
@files = files
|
||||
end
|
||||
|
||||
def env
|
||||
{ TILLER_NAMESPACE: namespace }
|
||||
end
|
||||
|
||||
def rbac?
|
||||
@rbac
|
||||
end
|
||||
|
||||
def pod_resource
|
||||
pod_service_account_name = rbac? ? service_account_name : nil
|
||||
|
||||
Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
|
||||
end
|
||||
|
||||
def generate_script
|
||||
<<~HEREDOC
|
||||
set -xeo pipefail
|
||||
HEREDOC
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"install-#{name}"
|
||||
end
|
||||
|
||||
def config_map_resource
|
||||
Gitlab::Kubernetes::ConfigMap.new(name, files).generate
|
||||
end
|
||||
|
||||
def service_account_resource
|
||||
return unless rbac?
|
||||
|
||||
Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
|
||||
end
|
||||
|
||||
def cluster_role_binding_resource
|
||||
return unless rbac?
|
||||
|
||||
subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
|
||||
|
||||
Gitlab::Kubernetes::ClusterRoleBinding.new(
|
||||
cluster_role_binding_name,
|
||||
cluster_role_name,
|
||||
subjects
|
||||
).generate
|
||||
end
|
||||
|
||||
def file_names
|
||||
files.keys
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def files_dir
|
||||
"/data/helm/#{name}/config"
|
||||
end
|
||||
|
||||
def namespace
|
||||
Gitlab::Kubernetes::Helm::NAMESPACE
|
||||
end
|
||||
|
||||
def service_account_name
|
||||
Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
|
||||
end
|
||||
|
||||
def cluster_role_binding_name
|
||||
Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
|
||||
end
|
||||
|
||||
def cluster_role_name
|
||||
Gitlab::Kubernetes::Helm::CLUSTER_ROLE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
# frozen_string_literal: true
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
class Certificate
|
||||
INFINITE_EXPIRY = 1000.years
|
||||
SHORT_EXPIRY = 30.minutes
|
||||
|
||||
attr_reader :key, :cert
|
||||
|
||||
def key_string
|
||||
@key.to_s
|
||||
end
|
||||
|
||||
def cert_string
|
||||
@cert.to_pem
|
||||
end
|
||||
|
||||
def self.from_strings(key_string, cert_string)
|
||||
key = OpenSSL::PKey::RSA.new(key_string)
|
||||
cert = OpenSSL::X509::Certificate.new(cert_string)
|
||||
new(key, cert)
|
||||
end
|
||||
|
||||
def self.generate_root
|
||||
_issue(signed_by: nil, expires_in: INFINITE_EXPIRY, certificate_authority: true)
|
||||
end
|
||||
|
||||
def issue(expires_in: SHORT_EXPIRY)
|
||||
self.class._issue(signed_by: self, expires_in: expires_in, certificate_authority: false)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self._issue(signed_by:, expires_in:, certificate_authority:)
|
||||
key = OpenSSL::PKey::RSA.new(4096)
|
||||
public_key = key.public_key
|
||||
|
||||
subject = OpenSSL::X509::Name.parse("/C=US")
|
||||
|
||||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.subject = subject
|
||||
|
||||
cert.issuer = signed_by&.cert&.subject || subject
|
||||
|
||||
cert.not_before = Time.now.utc
|
||||
cert.not_after = expires_in.from_now.utc
|
||||
cert.public_key = public_key
|
||||
cert.serial = 0x0
|
||||
cert.version = 2
|
||||
|
||||
if certificate_authority
|
||||
extension_factory = OpenSSL::X509::ExtensionFactory.new
|
||||
extension_factory.subject_certificate = cert
|
||||
extension_factory.issuer_certificate = cert
|
||||
cert.add_extension(extension_factory.create_extension('subjectKeyIdentifier', 'hash'))
|
||||
cert.add_extension(extension_factory.create_extension('basicConstraints', 'CA:TRUE', true))
|
||||
cert.add_extension(extension_factory.create_extension('keyUsage', 'cRLSign,keyCertSign', true))
|
||||
end
|
||||
|
||||
cert.sign(signed_by&.key || key, OpenSSL::Digest::SHA256.new)
|
||||
|
||||
new(key, cert)
|
||||
end
|
||||
|
||||
def initialize(key, cert)
|
||||
@key = key
|
||||
@cert = cert
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
module ClientCommand
|
||||
def init_command
|
||||
<<~SHELL.chomp
|
||||
export HELM_HOST="localhost:44134"
|
||||
tiller -listen ${HELM_HOST} -alsologtostderr &
|
||||
helm init --client-only
|
||||
SHELL
|
||||
end
|
||||
|
||||
def repository_command
|
||||
['helm', 'repo', 'add', name, repository].shelljoin if repository
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def repository_update_command
|
||||
'helm repo update'
|
||||
end
|
||||
|
||||
def optional_tls_flags
|
||||
return [] unless files.key?(:'ca.pem')
|
||||
|
||||
[
|
||||
'--tls',
|
||||
'--tls-ca-cert', "#{files_dir}/ca.pem",
|
||||
'--tls-cert', "#{files_dir}/cert.pem",
|
||||
'--tls-key', "#{files_dir}/key.pem"
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
class DeleteCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
attr_reader :predelete, :postdelete
|
||||
|
||||
def initialize(predelete: nil, postdelete: nil, **args)
|
||||
super(**args)
|
||||
@predelete = predelete
|
||||
@postdelete = postdelete
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
init_command,
|
||||
predelete,
|
||||
delete_command,
|
||||
postdelete
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"uninstall-#{name}"
|
||||
end
|
||||
|
||||
def delete_command
|
||||
['helm', 'delete', '--purge', name].shelljoin
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
class InitCommand < BaseCommand
|
||||
def generate_script
|
||||
super + [
|
||||
init_helm_command
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_helm_command
|
||||
command = %w[helm init] + init_command_flags
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def init_command_flags
|
||||
tls_flags + optional_service_account_flag
|
||||
end
|
||||
|
||||
def tls_flags
|
||||
[
|
||||
'--tiller-tls',
|
||||
'--tiller-tls-verify',
|
||||
'--tls-ca-cert', "#{files_dir}/ca.pem",
|
||||
'--tiller-tls-cert', "#{files_dir}/cert.pem",
|
||||
'--tiller-tls-key', "#{files_dir}/key.pem"
|
||||
]
|
||||
end
|
||||
|
||||
def optional_service_account_flag
|
||||
return [] unless rbac?
|
||||
|
||||
['--service-account', service_account_name]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
class InstallCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
attr_reader :chart, :repository, :preinstall, :postinstall
|
||||
attr_accessor :version
|
||||
|
||||
def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
|
||||
super(**args)
|
||||
@chart = chart
|
||||
@version = version
|
||||
@repository = repository
|
||||
@preinstall = preinstall
|
||||
@postinstall = postinstall
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
init_command,
|
||||
repository_command,
|
||||
repository_update_command,
|
||||
preinstall,
|
||||
install_command,
|
||||
postinstall
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Uses `helm upgrade --install` which means we can use this for both
|
||||
# installation and uprade of applications
|
||||
def install_command
|
||||
command = ['helm', 'upgrade', name, chart] +
|
||||
install_flag +
|
||||
rollback_support_flag +
|
||||
reset_values_flag +
|
||||
optional_version_flag +
|
||||
rbac_create_flag +
|
||||
namespace_flag +
|
||||
value_flag
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def install_flag
|
||||
['--install']
|
||||
end
|
||||
|
||||
def reset_values_flag
|
||||
['--reset-values']
|
||||
end
|
||||
|
||||
def value_flag
|
||||
['-f', "/data/helm/#{name}/config/values.yaml"]
|
||||
end
|
||||
|
||||
def namespace_flag
|
||||
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
|
||||
end
|
||||
|
||||
def rbac_create_flag
|
||||
if rbac?
|
||||
%w[--set rbac.create=true,rbac.enabled=true]
|
||||
else
|
||||
%w[--set rbac.create=false,rbac.enabled=false]
|
||||
end
|
||||
end
|
||||
|
||||
def optional_version_flag
|
||||
return [] unless version
|
||||
|
||||
['--version', version]
|
||||
end
|
||||
|
||||
def rollback_support_flag
|
||||
['--atomic', '--cleanup-on-fail']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# PatchCommand is for updating values in installed charts without overwriting
|
||||
# existing values.
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
class PatchCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
attr_reader :chart, :repository
|
||||
attr_accessor :version
|
||||
|
||||
def initialize(chart:, version:, repository: nil, **args)
|
||||
super(**args)
|
||||
|
||||
# version is mandatory to prevent chart mismatches
|
||||
# we do not want our values interpreted in the context of the wrong version
|
||||
raise ArgumentError, 'version is required' if version.blank?
|
||||
|
||||
@chart = chart
|
||||
@version = version
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
init_command,
|
||||
repository_command,
|
||||
repository_update_command,
|
||||
upgrade_command
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def upgrade_command
|
||||
command = ['helm', 'upgrade', name, chart] +
|
||||
reuse_values_flag +
|
||||
version_flag +
|
||||
namespace_flag +
|
||||
value_flag
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def reuse_values_flag
|
||||
['--reuse-values']
|
||||
end
|
||||
|
||||
def value_flag
|
||||
['-f', "/data/helm/#{name}/config/values.yaml"]
|
||||
end
|
||||
|
||||
def namespace_flag
|
||||
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
|
||||
end
|
||||
|
||||
def version_flag
|
||||
['--version', version]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V2
|
||||
class ResetCommand < BaseCommand
|
||||
include ClientCommand
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
reset_helm_command,
|
||||
delete_tiller_replicaset,
|
||||
delete_tiller_clusterrolebinding
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"uninstall-#{name}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# This method can be delete once we upgrade Helm to > 12.13.0
|
||||
# https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/27096#note_159695900
|
||||
#
|
||||
# Tracking this method to be removed here:
|
||||
# https://gitlab.com/gitlab-org/gitlab-foss/issues/52791#note_199374155
|
||||
def delete_tiller_replicaset
|
||||
delete_args = %w[replicaset -n gitlab-managed-apps -l name=tiller]
|
||||
|
||||
Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
|
||||
end
|
||||
|
||||
def delete_tiller_clusterrolebinding
|
||||
delete_args = %w[clusterrolebinding tiller-admin]
|
||||
|
||||
Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
|
||||
end
|
||||
|
||||
def reset_helm_command
|
||||
command = %w[helm reset] + optional_tls_flags
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V3
|
||||
class BaseCommand
|
||||
attr_reader :name, :files
|
||||
|
||||
HELM_VERSION = '3.2.4'
|
||||
|
||||
def initialize(rbac:, name:, files:)
|
||||
@rbac = rbac
|
||||
@name = name
|
||||
@files = files
|
||||
end
|
||||
|
||||
def env
|
||||
{}
|
||||
end
|
||||
|
||||
def rbac?
|
||||
@rbac
|
||||
end
|
||||
|
||||
def pod_resource
|
||||
pod_service_account_name = rbac? ? service_account_name : nil
|
||||
|
||||
Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
|
||||
end
|
||||
|
||||
def generate_script
|
||||
<<~HEREDOC
|
||||
set -xeo pipefail
|
||||
HEREDOC
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"install-#{name}"
|
||||
end
|
||||
|
||||
def config_map_resource
|
||||
Gitlab::Kubernetes::ConfigMap.new(name, files).generate
|
||||
end
|
||||
|
||||
def service_account_resource
|
||||
return unless rbac?
|
||||
|
||||
Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
|
||||
end
|
||||
|
||||
def cluster_role_binding_resource
|
||||
return unless rbac?
|
||||
|
||||
subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
|
||||
|
||||
Gitlab::Kubernetes::ClusterRoleBinding.new(
|
||||
cluster_role_binding_name,
|
||||
cluster_role_name,
|
||||
subjects
|
||||
).generate
|
||||
end
|
||||
|
||||
def file_names
|
||||
files.keys
|
||||
end
|
||||
|
||||
def repository_command
|
||||
['helm', 'repo', 'add', name, repository].shelljoin if repository
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def repository_update_command
|
||||
'helm repo update'
|
||||
end
|
||||
|
||||
def namespace_flag
|
||||
['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
|
||||
end
|
||||
|
||||
def namespace
|
||||
Gitlab::Kubernetes::Helm::NAMESPACE
|
||||
end
|
||||
|
||||
def service_account_name
|
||||
Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
|
||||
end
|
||||
|
||||
def cluster_role_binding_name
|
||||
Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
|
||||
end
|
||||
|
||||
def cluster_role_name
|
||||
Gitlab::Kubernetes::Helm::CLUSTER_ROLE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V3
|
||||
class DeleteCommand < BaseCommand
|
||||
attr_reader :predelete, :postdelete
|
||||
|
||||
def initialize(predelete: nil, postdelete: nil, **args)
|
||||
super(**args)
|
||||
@predelete = predelete
|
||||
@postdelete = postdelete
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
predelete,
|
||||
delete_command,
|
||||
postdelete
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
def pod_name
|
||||
"uninstall-#{name}"
|
||||
end
|
||||
|
||||
def delete_command
|
||||
['helm', 'uninstall', name, *namespace_flag].shelljoin
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V3
|
||||
class InstallCommand < BaseCommand
|
||||
attr_reader :chart, :repository, :preinstall, :postinstall
|
||||
attr_accessor :version
|
||||
|
||||
def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
|
||||
super(**args)
|
||||
@chart = chart
|
||||
@version = version
|
||||
@repository = repository
|
||||
@preinstall = preinstall
|
||||
@postinstall = postinstall
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
repository_command,
|
||||
repository_update_command,
|
||||
preinstall,
|
||||
install_command,
|
||||
postinstall
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Uses `helm upgrade --install` which means we can use this for both
|
||||
# installation and uprade of applications
|
||||
def install_command
|
||||
command = ['helm', 'upgrade', name, chart] +
|
||||
install_flag +
|
||||
rollback_support_flag +
|
||||
reset_values_flag +
|
||||
optional_version_flag +
|
||||
rbac_create_flag +
|
||||
namespace_flag +
|
||||
value_flag
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def install_flag
|
||||
['--install']
|
||||
end
|
||||
|
||||
def reset_values_flag
|
||||
['--reset-values']
|
||||
end
|
||||
|
||||
def value_flag
|
||||
['-f', "/data/helm/#{name}/config/values.yaml"]
|
||||
end
|
||||
|
||||
def rbac_create_flag
|
||||
if rbac?
|
||||
%w[--set rbac.create=true,rbac.enabled=true]
|
||||
else
|
||||
%w[--set rbac.create=false,rbac.enabled=false]
|
||||
end
|
||||
end
|
||||
|
||||
def optional_version_flag
|
||||
return [] unless version
|
||||
|
||||
['--version', version]
|
||||
end
|
||||
|
||||
def rollback_support_flag
|
||||
['--atomic', '--cleanup-on-fail']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# PatchCommand is for updating values in installed charts without overwriting
|
||||
# existing values.
|
||||
module Gitlab
|
||||
module Kubernetes
|
||||
module Helm
|
||||
module V3
|
||||
class PatchCommand < BaseCommand
|
||||
attr_reader :chart, :repository
|
||||
attr_accessor :version
|
||||
|
||||
def initialize(chart:, version:, repository: nil, **args)
|
||||
super(**args)
|
||||
|
||||
# version is mandatory to prevent chart mismatches
|
||||
# we do not want our values interpreted in the context of the wrong version
|
||||
raise ArgumentError, 'version is required' if version.blank?
|
||||
|
||||
@chart = chart
|
||||
@version = version
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def generate_script
|
||||
super + [
|
||||
repository_command,
|
||||
repository_update_command,
|
||||
upgrade_command
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def upgrade_command
|
||||
command = ['helm', 'upgrade', name, chart] +
|
||||
reuse_values_flag +
|
||||
version_flag +
|
||||
namespace_flag +
|
||||
value_flag
|
||||
|
||||
command.shelljoin
|
||||
end
|
||||
|
||||
def reuse_values_flag
|
||||
['--reuse-values']
|
||||
end
|
||||
|
||||
def value_flag
|
||||
['-f', "/data/helm/#{name}/config/values.yaml"]
|
||||
end
|
||||
|
||||
def version_flag
|
||||
['--version', version]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -18511,6 +18511,9 @@ msgstr ""
|
|||
msgid "Notes|This comment has changed since you started editing, please review the %{open_link}updated comment%{close_link} to ensure information is not lost"
|
||||
msgstr ""
|
||||
|
||||
msgid "Notes|You're only seeing %{boldStart}other activity%{boldEnd} in the feed. To add a comment, switch to one of the following options."
|
||||
msgstr ""
|
||||
|
||||
msgid "Nothing found…"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -30920,9 +30923,6 @@ msgstr ""
|
|||
msgid "You're not allowed to make changes to this project directly. A fork of this project is being created that you can make changes in, so you can submit a merge request."
|
||||
msgstr ""
|
||||
|
||||
msgid "You're only seeing %{startTag}other activity%{endTag} in the feed. To add a comment, switch to one of the following options."
|
||||
msgstr ""
|
||||
|
||||
msgid "You're receiving this email because of your account on %{host}."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ FactoryBot.define do
|
|||
cluster factory: %i(cluster provided_by_gcp)
|
||||
|
||||
before(:create) do
|
||||
allow(Gitlab::Kubernetes::Helm::Certificate).to receive(:generate_root)
|
||||
allow(Gitlab::Kubernetes::Helm::V2::Certificate).to receive(:generate_root)
|
||||
.and_return(
|
||||
double(
|
||||
key_string: File.read(Rails.root.join('spec/fixtures/clusters/sample_key.key')),
|
||||
|
|
@ -15,7 +15,7 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
after(:create) do
|
||||
allow(Gitlab::Kubernetes::Helm::Certificate).to receive(:generate_root).and_call_original
|
||||
allow(Gitlab::Kubernetes::Helm::V2::Certificate).to receive(:generate_root).and_call_original
|
||||
end
|
||||
|
||||
trait :not_installable do
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
},
|
||||
"commit_path": { "type": "string" },
|
||||
"tag_path": { "type": "string" },
|
||||
"name": { "type": "string" },
|
||||
"evidences": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "release/evidence.json" }
|
||||
|
|
@ -42,11 +41,8 @@
|
|||
"additionalProperties": false
|
||||
},
|
||||
"_links": {
|
||||
"required": ["merge_requests_url", "issues_url"],
|
||||
"properties": {
|
||||
"merge_requests_url": { "type": "string" },
|
||||
"issues_url": { "type": "string" },
|
||||
"edit_url": { "type": "string"}
|
||||
"edit_url": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -26,11 +26,7 @@
|
|||
"additionalProperties": false
|
||||
},
|
||||
"_links": {
|
||||
"required": ["merge_requests_url", "issues_url"],
|
||||
"properties": {
|
||||
"merge_requests_url": { "type": "string" },
|
||||
"issues_url": { "type": "string" }
|
||||
}
|
||||
"properties": {}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import { GlButton, GlSprintf } from '@gitlab/ui';
|
||||
import DiscussionFilterNote from '~/notes/components/discussion_filter_note.vue';
|
||||
import eventHub from '~/notes/event_hub';
|
||||
|
||||
|
|
@ -6,7 +7,11 @@ describe('DiscussionFilterNote component', () => {
|
|||
let wrapper;
|
||||
|
||||
const createComponent = () => {
|
||||
wrapper = shallowMount(DiscussionFilterNote);
|
||||
wrapper = shallowMount(DiscussionFilterNote, {
|
||||
stubs: {
|
||||
GlSprintf,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -19,21 +24,27 @@ describe('DiscussionFilterNote component', () => {
|
|||
});
|
||||
|
||||
it('timelineContent renders a string containing instruction for switching feed type', () => {
|
||||
expect(wrapper.find({ ref: 'timelineContent' }).html()).toBe(
|
||||
"<div>You're only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.</div>",
|
||||
expect(wrapper.find('[data-testid="discussion-filter-timeline-content"]').html()).toBe(
|
||||
'<div data-testid="discussion-filter-timeline-content">You\'re only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.</div>',
|
||||
);
|
||||
});
|
||||
|
||||
it('emits `dropdownSelect` event with 0 parameter on clicking Show all activity button', () => {
|
||||
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
|
||||
wrapper.find({ ref: 'showAllActivity' }).vm.$emit('click');
|
||||
wrapper
|
||||
.findAll(GlButton)
|
||||
.at(0)
|
||||
.vm.$emit('click');
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 0);
|
||||
});
|
||||
|
||||
it('emits `dropdownSelect` event with 1 parameter on clicking Show comments only button', () => {
|
||||
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
|
||||
wrapper.find({ ref: 'showComments' }).vm.$emit('click');
|
||||
wrapper
|
||||
.findAll(GlButton)
|
||||
.at(1)
|
||||
.vm.$emit('click');
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ RSpec.describe GitlabSchema.types['ReleaseLinks'] do
|
|||
openedIssuesUrl
|
||||
closedIssuesUrl
|
||||
editUrl
|
||||
mergeRequestsUrl
|
||||
issuesUrl
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
|
|
|
|||
|
|
@ -65,10 +65,22 @@ RSpec.describe Gitlab::ImportExport::Importer do
|
|||
end
|
||||
end
|
||||
|
||||
it 'restores the ProjectTree' do
|
||||
expect(Gitlab::ImportExport::Project::TreeRestorer).to receive(:new).and_call_original
|
||||
context 'with sample_data_template' do
|
||||
it 'initializes the Sample::TreeRestorer' do
|
||||
project.create_or_update_import_data(data: { sample_data: true })
|
||||
|
||||
importer.execute
|
||||
expect(Gitlab::ImportExport::Project::Sample::TreeRestorer).to receive(:new).and_call_original
|
||||
|
||||
importer.execute
|
||||
end
|
||||
end
|
||||
|
||||
context 'without sample_data_template' do
|
||||
it 'initializes the ProjectTree' do
|
||||
expect(Gitlab::ImportExport::Project::TreeRestorer).to receive(:new).and_call_original
|
||||
|
||||
importer.execute
|
||||
end
|
||||
end
|
||||
|
||||
it 'removes the import file' do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::ImportExport::Project::Sample::RelationFactory do
|
||||
let(:group) { create(:group) }
|
||||
let(:project) { create(:project, :repository, group: group) }
|
||||
let(:members_mapper) { double('members_mapper').as_null_object }
|
||||
let(:admin) { create(:admin) }
|
||||
let(:importer_user) { admin }
|
||||
let(:excluded_keys) { [] }
|
||||
let(:date_calculator) { instance_double(Gitlab::ImportExport::Project::Sample::DateCalculator) }
|
||||
let(:original_project_id) { 8 }
|
||||
let(:start_date) { Time.current - 30.days }
|
||||
let(:due_date) { Time.current - 20.days }
|
||||
let(:created_object) do
|
||||
described_class.create( # rubocop:disable Rails/SaveBang
|
||||
relation_sym: relation_sym,
|
||||
relation_hash: relation_hash,
|
||||
object_builder: Gitlab::ImportExport::Project::ObjectBuilder,
|
||||
members_mapper: members_mapper,
|
||||
user: importer_user,
|
||||
importable: project,
|
||||
excluded_keys: excluded_keys,
|
||||
date_calculator: date_calculator
|
||||
)
|
||||
end
|
||||
|
||||
context 'issue object' do
|
||||
let(:relation_sym) { :issues }
|
||||
let(:id) { 999 }
|
||||
|
||||
let(:relation_hash) do
|
||||
{
|
||||
'id' => id,
|
||||
'title' => 'Necessitatibus magnam qui at velit consequatur perspiciatis.',
|
||||
'project_id' => original_project_id,
|
||||
'created_at' => '2016-08-12T09:41:03.462Z',
|
||||
'updated_at' => '2016-08-12T09:41:03.462Z',
|
||||
'description' => 'Molestiae corporis magnam et fugit aliquid nulla quia.',
|
||||
'state' => 'closed',
|
||||
'position' => 0,
|
||||
'confidential' => false,
|
||||
'due_date' => due_date
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(date_calculator).to receive(:closest_date_to_average) { Time.current - 10.days }
|
||||
allow(date_calculator).to receive(:calculate_by_closest_date_to_average)
|
||||
end
|
||||
|
||||
it 'correctly updated due date', :aggregate_failures do
|
||||
expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
|
||||
.with(relation_hash['due_date']).and_return(due_date - 10.days)
|
||||
|
||||
expect(created_object.due_date).to eq((due_date - 10.days).to_date)
|
||||
end
|
||||
end
|
||||
|
||||
context 'milestone object' do
|
||||
let(:relation_sym) { :milestones }
|
||||
let(:id) { 1001 }
|
||||
|
||||
let(:relation_hash) do
|
||||
{
|
||||
'id' => id,
|
||||
'title' => 'v3.0',
|
||||
'project_id' => original_project_id,
|
||||
'created_at' => '2016-08-12T09:41:03.462Z',
|
||||
'updated_at' => '2016-08-12T09:41:03.462Z',
|
||||
'description' => 'Rerum at autem exercitationem ea voluptates harum quam placeat.',
|
||||
'state' => 'closed',
|
||||
'start_date' => start_date,
|
||||
'due_date' => due_date
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(date_calculator).to receive(:closest_date_to_average).twice { Time.current - 10.days }
|
||||
allow(date_calculator).to receive(:calculate_by_closest_date_to_average).twice
|
||||
end
|
||||
|
||||
it 'correctly updated due date', :aggregate_failures do
|
||||
expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
|
||||
.with(relation_hash['due_date']).and_return(due_date - 10.days)
|
||||
|
||||
expect(created_object.due_date).to eq((due_date - 10.days).to_date)
|
||||
end
|
||||
|
||||
it 'correctly updated start date', :aggregate_failures do
|
||||
expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
|
||||
.with(relation_hash['start_date']).and_return(start_date - 20.days)
|
||||
|
||||
expect(created_object.start_date).to eq((start_date - 20.days).to_date)
|
||||
end
|
||||
end
|
||||
|
||||
context 'milestone object' do
|
||||
let(:relation_sym) { :milestones }
|
||||
let(:id) { 1001 }
|
||||
|
||||
let(:relation_hash) do
|
||||
{
|
||||
'id' => id,
|
||||
'title' => 'v3.0',
|
||||
'project_id' => original_project_id,
|
||||
'created_at' => '2016-08-12T09:41:03.462Z',
|
||||
'updated_at' => '2016-08-12T09:41:03.462Z',
|
||||
'description' => 'Rerum at autem exercitationem ea voluptates harum quam placeat.',
|
||||
'state' => 'closed',
|
||||
'start_date' => start_date,
|
||||
'due_date' => due_date
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(date_calculator).to receive(:closest_date_to_average).twice { Time.current - 10.days }
|
||||
allow(date_calculator).to receive(:calculate_by_closest_date_to_average).twice
|
||||
end
|
||||
|
||||
it 'correctly updated due date', :aggregate_failures do
|
||||
expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
|
||||
.with(relation_hash['due_date']).and_return(due_date - 10.days)
|
||||
|
||||
expect(created_object.due_date).to eq((due_date - 10.days).to_date)
|
||||
end
|
||||
|
||||
it 'correctly updated start date', :aggregate_failures do
|
||||
expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
|
||||
.with(relation_hash['start_date']).and_return(start_date - 20.days)
|
||||
|
||||
expect(created_object.start_date).to eq((start_date - 20.days).to_date)
|
||||
end
|
||||
end
|
||||
|
||||
context 'hook object' do
|
||||
let(:relation_sym) { :hooks }
|
||||
let(:id) { 999 }
|
||||
let(:service_id) { 99 }
|
||||
let(:token) { 'secret' }
|
||||
|
||||
let(:relation_hash) do
|
||||
{
|
||||
'id' => id,
|
||||
'url' => 'https://example.json',
|
||||
'project_id' => original_project_id,
|
||||
'created_at' => '2016-08-12T09:41:03.462Z',
|
||||
'updated_at' => '2016-08-12T09:41:03.462Z',
|
||||
'service_id' => service_id,
|
||||
'push_events' => true,
|
||||
'issues_events' => false,
|
||||
'confidential_issues_events' => false,
|
||||
'merge_requests_events' => true,
|
||||
'tag_push_events' => false,
|
||||
'note_events' => true,
|
||||
'enable_ssl_verification' => true,
|
||||
'job_events' => false,
|
||||
'wiki_page_events' => true,
|
||||
'token' => token
|
||||
}
|
||||
end
|
||||
|
||||
it 'does not calculate the closest date to average' do
|
||||
expect(date_calculator).not_to receive(:calculate_by_closest_date_to_average)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::ImportExport::Project::Sample::SampleDataRelationTreeRestorer do
|
||||
RSpec.describe Gitlab::ImportExport::Project::Sample::RelationTreeRestorer do
|
||||
include_context 'relation tree restorer shared context'
|
||||
|
||||
let(:sample_data_relation_tree_restorer) do
|
||||
|
|
@ -74,13 +74,26 @@ RSpec.describe Gitlab::ImportExport::Project::Sample::SampleDataRelationTreeRest
|
|||
let(:importable_name) { 'project' }
|
||||
let(:importable_path) { 'project' }
|
||||
let(:object_builder) { Gitlab::ImportExport::Project::ObjectBuilder }
|
||||
let(:relation_factory) { Gitlab::ImportExport::Project::RelationFactory }
|
||||
let(:relation_factory) { Gitlab::ImportExport::Project::Sample::RelationFactory }
|
||||
let(:reader) { Gitlab::ImportExport::Reader.new(shared: shared) }
|
||||
let(:path) { 'spec/fixtures/lib/gitlab/import_export/sample_data/tree' }
|
||||
let(:relation_reader) { Gitlab::ImportExport::JSON::NdjsonReader.new(path) }
|
||||
|
||||
it 'initializes relation_factory with date_calculator as parameter' do
|
||||
expect(Gitlab::ImportExport::Project::Sample::RelationFactory).to receive(:create).with(hash_including(:date_calculator)).at_least(:once).times
|
||||
|
||||
subject
|
||||
end
|
||||
|
||||
context 'when relation tree restorer is initialized' do
|
||||
it 'initializes date calculator with due dates' do
|
||||
expect(Gitlab::ImportExport::Project::Sample::DateCalculator).to receive(:new).with(Array)
|
||||
|
||||
sample_data_relation_tree_restorer
|
||||
end
|
||||
end
|
||||
|
||||
context 'using ndjson reader' do
|
||||
let(:path) { 'spec/fixtures/lib/gitlab/import_export/sample_data/tree' }
|
||||
let(:relation_reader) { Gitlab::ImportExport::JSON::NdjsonReader.new(path) }
|
||||
|
||||
it_behaves_like 'import project successfully'
|
||||
end
|
||||
end
|
||||
|
|
@ -1040,41 +1040,6 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
|
|||
it_behaves_like 'project tree restorer work properly', :legacy_reader, true
|
||||
|
||||
it_behaves_like 'project tree restorer work properly', :ndjson_reader, true
|
||||
|
||||
context 'Sample Data JSON' do
|
||||
let(:user) { create(:user) }
|
||||
let!(:project) { create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') }
|
||||
let(:project_tree_restorer) { described_class.new(user: user, shared: shared, project: project) }
|
||||
|
||||
before do
|
||||
setup_import_export_config('sample_data')
|
||||
setup_reader(:ndjson_reader)
|
||||
end
|
||||
|
||||
context 'with sample_data_template' do
|
||||
before do
|
||||
allow(project).to receive_message_chain(:import_data, :data, :dig).with('sample_data') { true }
|
||||
end
|
||||
|
||||
it 'initialize SampleDataRelationTreeRestorer' do
|
||||
expect_next_instance_of(Gitlab::ImportExport::Project::Sample::SampleDataRelationTreeRestorer) do |restorer|
|
||||
expect(restorer).to receive(:restore).and_return(true)
|
||||
end
|
||||
|
||||
expect(project_tree_restorer.restore).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without sample_data_template' do
|
||||
it 'initialize RelationTreeRestorer' do
|
||||
expect_next_instance_of(Gitlab::ImportExport::RelationTreeRestorer) do |restorer|
|
||||
expect(restorer).to receive(:restore).and_return(true)
|
||||
end
|
||||
|
||||
expect(project_tree_restorer.restore).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'disable ndjson import' do
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ RSpec.describe Gitlab::Kubernetes::Helm::API do
|
|||
let(:files) { {} }
|
||||
|
||||
let(:command) do
|
||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||
Gitlab::Kubernetes::Helm::V2::InstallCommand.new(
|
||||
name: application_name,
|
||||
chart: 'chart-name',
|
||||
rbac: rbac,
|
||||
|
|
@ -142,7 +142,7 @@ RSpec.describe Gitlab::Kubernetes::Helm::API do
|
|||
end
|
||||
|
||||
context 'with a service account' do
|
||||
let(:command) { Gitlab::Kubernetes::Helm::InitCommand.new(name: application_name, files: files, rbac: rbac) }
|
||||
let(:command) { Gitlab::Kubernetes::Helm::V2::InitCommand.new(name: application_name, files: files, rbac: rbac) }
|
||||
|
||||
context 'rbac-enabled cluster' do
|
||||
let(:rbac) { true }
|
||||
|
|
|
|||
|
|
@ -4,75 +4,84 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::Pod do
|
||||
describe '#generate' do
|
||||
let(:app) { create(:clusters_applications_prometheus) }
|
||||
let(:command) { app.install_command }
|
||||
let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
|
||||
let(:service_account_name) { nil }
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
subject { described_class.new(command, namespace, service_account_name: service_account_name) }
|
||||
where(:helm_major_version, :expected_helm_version, :expected_command_env) do
|
||||
2 | '2.16.9' | [:TILLER_NAMESPACE]
|
||||
3 | '3.2.4' | nil
|
||||
end
|
||||
|
||||
context 'with a command' do
|
||||
it 'generates a Kubeclient::Resource' do
|
||||
expect(subject.generate).to be_a_kind_of(Kubeclient::Resource)
|
||||
end
|
||||
with_them do
|
||||
let(:cluster) { create(:cluster, helm_major_version: helm_major_version) }
|
||||
let(:app) { create(:clusters_applications_prometheus, cluster: cluster) }
|
||||
let(:command) { app.install_command }
|
||||
let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
|
||||
let(:service_account_name) { nil }
|
||||
|
||||
it 'generates the appropriate metadata' do
|
||||
metadata = subject.generate.metadata
|
||||
expect(metadata.name).to eq("install-#{app.name}")
|
||||
expect(metadata.namespace).to eq('gitlab-managed-apps')
|
||||
expect(metadata.labels['gitlab.org/action']).to eq('install')
|
||||
expect(metadata.labels['gitlab.org/application']).to eq(app.name)
|
||||
end
|
||||
subject { described_class.new(command, namespace, service_account_name: service_account_name) }
|
||||
|
||||
it 'generates a container spec' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.containers.count).to eq(1)
|
||||
end
|
||||
context 'with a command' do
|
||||
it 'generates a Kubeclient::Resource' do
|
||||
expect(subject.generate).to be_a_kind_of(Kubeclient::Resource)
|
||||
end
|
||||
|
||||
it 'generates the appropriate specifications for the container' do
|
||||
container = subject.generate.spec.containers.first
|
||||
expect(container.name).to eq('helm')
|
||||
expect(container.image).to eq('registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/2.16.9-kube-1.13.12')
|
||||
expect(container.env.count).to eq(3)
|
||||
expect(container.env.map(&:name)).to match_array([:HELM_VERSION, :TILLER_NAMESPACE, :COMMAND_SCRIPT])
|
||||
expect(container.command).to match_array(["/bin/sh"])
|
||||
expect(container.args).to match_array(["-c", "$(COMMAND_SCRIPT)"])
|
||||
end
|
||||
it 'generates the appropriate metadata' do
|
||||
metadata = subject.generate.metadata
|
||||
expect(metadata.name).to eq("install-#{app.name}")
|
||||
expect(metadata.namespace).to eq('gitlab-managed-apps')
|
||||
expect(metadata.labels['gitlab.org/action']).to eq('install')
|
||||
expect(metadata.labels['gitlab.org/application']).to eq(app.name)
|
||||
end
|
||||
|
||||
it 'includes a never restart policy' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.restartPolicy).to eq('Never')
|
||||
end
|
||||
|
||||
it 'includes volumes for the container' do
|
||||
container = subject.generate.spec.containers.first
|
||||
expect(container.volumeMounts.first['name']).to eq('configuration-volume')
|
||||
expect(container.volumeMounts.first['mountPath']).to eq("/data/helm/#{app.name}/config")
|
||||
end
|
||||
|
||||
it 'includes a volume inside the specification' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.volumes.first['name']).to eq('configuration-volume')
|
||||
end
|
||||
|
||||
it 'mounts configMap specification in the volume' do
|
||||
volume = subject.generate.spec.volumes.first
|
||||
expect(volume.configMap['name']).to eq("values-content-configuration-#{app.name}")
|
||||
expect(volume.configMap['items'].first['key']).to eq(:'values.yaml')
|
||||
expect(volume.configMap['items'].first['path']).to eq(:'values.yaml')
|
||||
end
|
||||
|
||||
it 'has no serviceAccountName' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.serviceAccountName).to be_nil
|
||||
end
|
||||
|
||||
context 'with a service_account_name' do
|
||||
let(:service_account_name) { 'sa' }
|
||||
|
||||
it 'uses the serviceAccountName provided' do
|
||||
it 'generates a container spec' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.serviceAccountName).to eq(service_account_name)
|
||||
expect(spec.containers.count).to eq(1)
|
||||
end
|
||||
|
||||
it 'generates the appropriate specifications for the container' do
|
||||
container = subject.generate.spec.containers.first
|
||||
expect(container.name).to eq('helm')
|
||||
expect(container.image).to eq("registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/#{expected_helm_version}-kube-1.13.12-alpine-3.12")
|
||||
expect(container.env.map(&:name)).to include(:HELM_VERSION, :COMMAND_SCRIPT, *expected_command_env)
|
||||
expect(container.command).to match_array(["/bin/sh"])
|
||||
expect(container.args).to match_array(["-c", "$(COMMAND_SCRIPT)"])
|
||||
end
|
||||
|
||||
it 'includes a never restart policy' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.restartPolicy).to eq('Never')
|
||||
end
|
||||
|
||||
it 'includes volumes for the container' do
|
||||
container = subject.generate.spec.containers.first
|
||||
expect(container.volumeMounts.first['name']).to eq('configuration-volume')
|
||||
expect(container.volumeMounts.first['mountPath']).to eq("/data/helm/#{app.name}/config")
|
||||
end
|
||||
|
||||
it 'includes a volume inside the specification' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.volumes.first['name']).to eq('configuration-volume')
|
||||
end
|
||||
|
||||
it 'mounts configMap specification in the volume' do
|
||||
volume = subject.generate.spec.volumes.first
|
||||
expect(volume.configMap['name']).to eq("values-content-configuration-#{app.name}")
|
||||
expect(volume.configMap['items'].first['key']).to eq(:'values.yaml')
|
||||
expect(volume.configMap['items'].first['path']).to eq(:'values.yaml')
|
||||
end
|
||||
|
||||
it 'has no serviceAccountName' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.serviceAccountName).to be_nil
|
||||
end
|
||||
|
||||
context 'with a service_account_name' do
|
||||
let(:service_account_name) { 'sa' }
|
||||
|
||||
it 'uses the serviceAccountName provided' do
|
||||
spec = subject.generate.spec
|
||||
expect(spec.serviceAccountName).to eq(service_account_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V2::BaseCommand do
|
||||
subject(:base_command) do
|
||||
test_class.new(rbac)
|
||||
end
|
||||
|
||||
let(:application) { create(:clusters_applications_helm) }
|
||||
let(:rbac) { false }
|
||||
|
||||
let(:test_class) do
|
||||
Class.new(described_class) do
|
||||
def initialize(rbac)
|
||||
super(
|
||||
name: 'test-class-name',
|
||||
rbac: rbac,
|
||||
files: { some: 'value' }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'HELM_VERSION' do
|
||||
subject { described_class::HELM_VERSION }
|
||||
|
||||
it { is_expected.to match /^2\.\d+\.\d+$/ }
|
||||
end
|
||||
|
||||
describe '#env' do
|
||||
subject { base_command.env }
|
||||
|
||||
it { is_expected.to include(TILLER_NAMESPACE: 'gitlab-managed-apps') }
|
||||
end
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) { '' }
|
||||
end
|
||||
|
||||
describe '#pod_name' do
|
||||
subject { base_command.pod_name }
|
||||
|
||||
it { is_expected.to eq('install-test-class-name') }
|
||||
end
|
||||
|
||||
it_behaves_like 'helm command' do
|
||||
let(:command) { base_command }
|
||||
end
|
||||
end
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::Certificate do
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V2::Certificate do
|
||||
describe '.generate_root' do
|
||||
subject { described_class.generate_root }
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::DeleteCommand do
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V2::DeleteCommand do
|
||||
subject(:delete_command) { described_class.new(name: app_name, rbac: rbac, files: files) }
|
||||
|
||||
let(:app_name) { 'app-name' }
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::InitCommand do
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V2::InitCommand do
|
||||
subject(:init_command) { described_class.new(name: application.name, files: files, rbac: rbac) }
|
||||
|
||||
let(:application) { create(:clusters_applications_helm) }
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::InstallCommand do
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V2::InstallCommand do
|
||||
subject(:install_command) do
|
||||
described_class.new(
|
||||
name: 'app-name',
|
||||
|
|
@ -147,37 +147,6 @@ RSpec.describe Gitlab::Kubernetes::Helm::InstallCommand do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when there is no ca.pem file' do
|
||||
let(:files) { { 'file.txt': 'some content' } }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
export HELM_HOST="localhost:44134"
|
||||
tiller -listen ${HELM_HOST} -alsologtostderr &
|
||||
helm init --client-only
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_install_command}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_install_command) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--install
|
||||
--atomic
|
||||
--cleanup-on-fail
|
||||
--reset-values
|
||||
--version 1.2.3
|
||||
--set rbac.create\\=false,rbac.enabled\\=false
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no version' do
|
||||
let(:version) { nil }
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::PatchCommand do
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V2::PatchCommand do
|
||||
let(:files) { { 'ca.pem': 'some file content' } }
|
||||
let(:repository) { 'https://repository.example.com' }
|
||||
let(:rbac) { false }
|
||||
|
|
@ -69,33 +69,6 @@ RSpec.describe Gitlab::Kubernetes::Helm::PatchCommand do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when there is no ca.pem file' do
|
||||
let(:files) { { 'file.txt': 'some content' } }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
export HELM_HOST="localhost:44134"
|
||||
tiller -listen ${HELM_HOST} -alsologtostderr &
|
||||
helm init --client-only
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_upgrade_command}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_upgrade_command) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--reuse-values
|
||||
--version 1.2.3
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no version' do
|
||||
let(:version) { nil }
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::ResetCommand do
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V2::ResetCommand do
|
||||
subject(:reset_command) { described_class.new(name: name, rbac: rbac, files: files) }
|
||||
|
||||
let(:rbac) { true }
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::BaseCommand do
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V3::BaseCommand do
|
||||
subject(:base_command) do
|
||||
test_class.new(rbac)
|
||||
end
|
||||
|
|
@ -11,7 +11,7 @@ RSpec.describe Gitlab::Kubernetes::Helm::BaseCommand do
|
|||
let(:rbac) { false }
|
||||
|
||||
let(:test_class) do
|
||||
Class.new(Gitlab::Kubernetes::Helm::BaseCommand) do
|
||||
Class.new(described_class) do
|
||||
def initialize(rbac)
|
||||
super(
|
||||
name: 'test-class-name',
|
||||
|
|
@ -22,6 +22,12 @@ RSpec.describe Gitlab::Kubernetes::Helm::BaseCommand do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'HELM_VERSION' do
|
||||
subject { described_class::HELM_VERSION }
|
||||
|
||||
it { is_expected.to match /^3\.\d+\.\d+$/ }
|
||||
end
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) { '' }
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V3::DeleteCommand do
|
||||
subject(:delete_command) { described_class.new(name: app_name, rbac: rbac, files: files) }
|
||||
|
||||
let(:app_name) { 'app-name' }
|
||||
let(:rbac) { true }
|
||||
let(:files) { {} }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm uninstall app-name --namespace gitlab-managed-apps
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pod_name' do
|
||||
subject { delete_command.pod_name }
|
||||
|
||||
it { is_expected.to eq('uninstall-app-name') }
|
||||
end
|
||||
|
||||
it_behaves_like 'helm command' do
|
||||
let(:command) { delete_command }
|
||||
end
|
||||
|
||||
describe '#delete_command' do
|
||||
it 'deletes the release' do
|
||||
expect(subject.delete_command).to eq('helm uninstall app-name --namespace gitlab-managed-apps')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V3::InstallCommand do
|
||||
subject(:install_command) do
|
||||
described_class.new(
|
||||
name: 'app-name',
|
||||
chart: 'chart-name',
|
||||
rbac: rbac,
|
||||
files: files,
|
||||
version: version,
|
||||
repository: repository,
|
||||
preinstall: preinstall,
|
||||
postinstall: postinstall
|
||||
)
|
||||
end
|
||||
|
||||
let(:files) { { 'ca.pem': 'some file content' } }
|
||||
let(:repository) { 'https://repository.example.com' }
|
||||
let(:rbac) { false }
|
||||
let(:version) { '1.2.3' }
|
||||
let(:preinstall) { nil }
|
||||
let(:postinstall) { nil }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_install_comand}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_install_comand) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--install
|
||||
--atomic
|
||||
--cleanup-on-fail
|
||||
--reset-values
|
||||
--version 1.2.3
|
||||
--set rbac.create\\=false,rbac.enabled\\=false
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
context 'when rbac is true' do
|
||||
let(:rbac) { true }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_install_command}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_install_command) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--install
|
||||
--atomic
|
||||
--cleanup-on-fail
|
||||
--reset-values
|
||||
--version 1.2.3
|
||||
--set rbac.create\\=true,rbac.enabled\\=true
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a pre-install script' do
|
||||
let(:preinstall) { ['/bin/date', '/bin/true'] }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
/bin/date
|
||||
/bin/true
|
||||
#{helm_install_command}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_install_command) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--install
|
||||
--atomic
|
||||
--cleanup-on-fail
|
||||
--reset-values
|
||||
--version 1.2.3
|
||||
--set rbac.create\\=false,rbac.enabled\\=false
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a post-install script' do
|
||||
let(:postinstall) { ['/bin/date', "/bin/false\n"] }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_install_command}
|
||||
/bin/date
|
||||
/bin/false
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_install_command) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--install
|
||||
--atomic
|
||||
--cleanup-on-fail
|
||||
--reset-values
|
||||
--version 1.2.3
|
||||
--set rbac.create\\=false,rbac.enabled\\=false
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no version' do
|
||||
let(:version) { nil }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_install_command}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_install_command) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--install
|
||||
--atomic
|
||||
--cleanup-on-fail
|
||||
--reset-values
|
||||
--set rbac.create\\=false,rbac.enabled\\=false
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'helm command' do
|
||||
let(:command) { install_command }
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Kubernetes::Helm::V3::PatchCommand do
|
||||
let(:files) { { 'ca.pem': 'some file content' } }
|
||||
let(:repository) { 'https://repository.example.com' }
|
||||
let(:rbac) { false }
|
||||
let(:version) { '1.2.3' }
|
||||
|
||||
subject(:patch_command) do
|
||||
described_class.new(
|
||||
name: 'app-name',
|
||||
chart: 'chart-name',
|
||||
rbac: rbac,
|
||||
files: files,
|
||||
version: version,
|
||||
repository: repository
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_upgrade_comand}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_upgrade_comand) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--reuse-values
|
||||
--version 1.2.3
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
context 'when rbac is true' do
|
||||
let(:rbac) { true }
|
||||
|
||||
it_behaves_like 'helm command generator' do
|
||||
let(:commands) do
|
||||
<<~EOS
|
||||
helm repo add app-name https://repository.example.com
|
||||
helm repo update
|
||||
#{helm_upgrade_command}
|
||||
EOS
|
||||
end
|
||||
|
||||
let(:helm_upgrade_command) do
|
||||
<<~EOS.squish
|
||||
helm upgrade app-name chart-name
|
||||
--reuse-values
|
||||
--version 1.2.3
|
||||
--namespace gitlab-managed-apps
|
||||
-f /data/helm/app-name/config/values.yaml
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no version' do
|
||||
let(:version) { nil }
|
||||
|
||||
it { expect { patch_command }.to raise_error(ArgumentError, 'version is required') }
|
||||
end
|
||||
|
||||
describe '#pod_name' do
|
||||
subject { patch_command.pod_name }
|
||||
|
||||
it { is_expected.to eq 'install-app-name' }
|
||||
end
|
||||
|
||||
it_behaves_like 'helm command' do
|
||||
let(:command) { patch_command }
|
||||
end
|
||||
end
|
||||
|
|
@ -40,7 +40,7 @@ RSpec.describe Clusters::Applications::CertManager do
|
|||
|
||||
subject { cert_manager.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with cert_manager arguments' do
|
||||
expect(subject.name).to eq('certmanager')
|
||||
|
|
@ -90,7 +90,7 @@ RSpec.describe Clusters::Applications::CertManager do
|
|||
describe '#uninstall_command' do
|
||||
subject { cert_manager.uninstall_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
|
||||
|
||||
it 'is initialized with cert_manager arguments' do
|
||||
expect(subject.name).to eq('certmanager')
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ RSpec.describe Clusters::Applications::Crossplane do
|
|||
|
||||
subject { crossplane.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with crossplane arguments' do
|
||||
expect(subject.name).to eq('crossplane')
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
|
|||
|
||||
subject { elastic_stack.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with elastic stack arguments' do
|
||||
expect(subject.name).to eq('elastic-stack')
|
||||
|
|
@ -57,7 +57,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
|
|||
|
||||
it 'includes a preinstall script' do
|
||||
expect(subject.preinstall).not_to be_empty
|
||||
expect(subject.preinstall.first).to include("delete")
|
||||
expect(subject.preinstall.first).to include("helm uninstall")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
|
|||
|
||||
it 'includes a preinstall script' do
|
||||
expect(subject.preinstall).not_to be_empty
|
||||
expect(subject.preinstall.first).to include("delete")
|
||||
expect(subject.preinstall.first).to include("helm uninstall")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
|
|||
|
||||
subject { elastic_stack.uninstall_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
|
||||
|
||||
it 'is initialized with elastic stack arguments' do
|
||||
expect(subject.name).to eq('elastic-stack')
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ RSpec.describe Clusters::Applications::Fluentd do
|
|||
describe '#install_command' do
|
||||
subject { fluentd.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with fluentd arguments' do
|
||||
expect(subject.name).to eq('fluentd')
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ RSpec.describe Clusters::Applications::Helm do
|
|||
subject { application.issue_client_cert }
|
||||
|
||||
it 'returns a new cert' do
|
||||
is_expected.to be_kind_of(Gitlab::Kubernetes::Helm::Certificate)
|
||||
is_expected.to be_kind_of(Gitlab::Kubernetes::Helm::V2::Certificate)
|
||||
expect(subject.cert_string).not_to eq(application.ca_cert)
|
||||
expect(subject.key_string).not_to eq(application.ca_key)
|
||||
end
|
||||
|
|
@ -67,7 +67,7 @@ RSpec.describe Clusters::Applications::Helm do
|
|||
|
||||
subject { helm.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InitCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V2::InitCommand) }
|
||||
|
||||
it 'is initialized with 1 arguments' do
|
||||
expect(subject.name).to eq('helm')
|
||||
|
|
@ -104,7 +104,7 @@ RSpec.describe Clusters::Applications::Helm do
|
|||
|
||||
subject { helm.uninstall_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::ResetCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V2::ResetCommand) }
|
||||
|
||||
it 'has name' do
|
||||
expect(subject.name).to eq('helm')
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ RSpec.describe Clusters::Applications::Ingress do
|
|||
describe '#install_command' do
|
||||
subject { ingress.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with ingress arguments' do
|
||||
expect(subject.name).to eq('ingress')
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ RSpec.describe Clusters::Applications::Jupyter do
|
|||
|
||||
subject { jupyter.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with 4 arguments' do
|
||||
expect(subject.name).to eq('jupyter')
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ RSpec.describe Clusters::Applications::Knative do
|
|||
|
||||
shared_examples 'a command' do
|
||||
it 'is an instance of Helm::InstallCommand' do
|
||||
expect(subject).to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand)
|
||||
expect(subject).to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand)
|
||||
end
|
||||
|
||||
it 'is initialized with knative arguments' do
|
||||
|
|
@ -171,7 +171,7 @@ RSpec.describe Clusters::Applications::Knative do
|
|||
describe '#uninstall_command' do
|
||||
subject { knative.uninstall_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
|
||||
|
||||
it "removes knative deployed services before uninstallation" do
|
||||
2.times do |i|
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ RSpec.describe Clusters::Applications::Prometheus do
|
|||
|
||||
subject { prometheus.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with 3 arguments' do
|
||||
expect(subject.name).to eq('prometheus')
|
||||
|
|
@ -195,7 +195,7 @@ RSpec.describe Clusters::Applications::Prometheus do
|
|||
|
||||
subject { prometheus.uninstall_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
|
||||
|
||||
it 'has the application name' do
|
||||
expect(subject.name).to eq('prometheus')
|
||||
|
|
@ -236,7 +236,7 @@ RSpec.describe Clusters::Applications::Prometheus do
|
|||
let(:prometheus) { build(:clusters_applications_prometheus) }
|
||||
let(:values) { prometheus.values }
|
||||
|
||||
it { is_expected.to be_an_instance_of(::Gitlab::Kubernetes::Helm::PatchCommand) }
|
||||
it { is_expected.to be_an_instance_of(::Gitlab::Kubernetes::Helm::V3::PatchCommand) }
|
||||
|
||||
it 'is initialized with 3 arguments' do
|
||||
expect(patch_command.name).to eq('prometheus')
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ RSpec.describe Clusters::Applications::Runner do
|
|||
|
||||
subject { gitlab_runner.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
|
||||
|
||||
it 'is initialized with 4 arguments' do
|
||||
expect(subject.name).to eq('runner')
|
||||
|
|
|
|||
|
|
@ -540,6 +540,27 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'helm_major_version can only be 2 or 3' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:helm_major_version, :expect_valid) do
|
||||
2 | true
|
||||
3 | true
|
||||
4 | false
|
||||
-1 | false
|
||||
end
|
||||
|
||||
with_them do
|
||||
let(:cluster) { build(:cluster, helm_major_version: helm_major_version) }
|
||||
|
||||
it { is_expected.to eq(expect_valid) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'has default helm_major_version 3' do
|
||||
expect(create(:cluster).helm_major_version).to eq(3)
|
||||
end
|
||||
|
||||
describe '.ancestor_clusters_for_clusterable' do
|
||||
|
|
|
|||
|
|
@ -189,8 +189,6 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
|
|||
closedMergeRequestsUrl
|
||||
openedIssuesUrl
|
||||
closedIssuesUrl
|
||||
mergeRequestsUrl
|
||||
issuesUrl
|
||||
})
|
||||
end
|
||||
|
||||
|
|
@ -203,9 +201,7 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
|
|||
'mergedMergeRequestsUrl' => project_merge_requests_url(project, merged_url_params),
|
||||
'closedMergeRequestsUrl' => project_merge_requests_url(project, closed_url_params),
|
||||
'openedIssuesUrl' => project_issues_url(project, opened_url_params),
|
||||
'closedIssuesUrl' => project_issues_url(project, closed_url_params),
|
||||
'mergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
|
||||
'issuesUrl' => project_issues_url(project, opened_url_params)
|
||||
'closedIssuesUrl' => project_issues_url(project, closed_url_params)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -47,8 +47,6 @@ RSpec.describe 'Query.project(fullPath).releases()' do
|
|||
closedMergeRequestsUrl
|
||||
openedIssuesUrl
|
||||
closedIssuesUrl
|
||||
mergeRequestsUrl
|
||||
issuesUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -115,9 +113,7 @@ RSpec.describe 'Query.project(fullPath).releases()' do
|
|||
'mergedMergeRequestsUrl' => project_merge_requests_url(project, merged_url_params),
|
||||
'closedMergeRequestsUrl' => project_merge_requests_url(project, closed_url_params),
|
||||
'openedIssuesUrl' => project_issues_url(project, opened_url_params),
|
||||
'closedIssuesUrl' => project_issues_url(project, closed_url_params),
|
||||
'mergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
|
||||
'issuesUrl' => project_issues_url(project, opened_url_params)
|
||||
'closedIssuesUrl' => project_issues_url(project, closed_url_params)
|
||||
}
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -110,22 +110,6 @@ RSpec.describe API::Releases do
|
|||
expect(json_response.second['commit_path']).to eq("/#{release_1.project.full_path}/-/commit/#{release_1.commit.id}")
|
||||
expect(json_response.second['tag_path']).to eq("/#{release_1.project.full_path}/-/tags/#{release_1.tag}")
|
||||
end
|
||||
|
||||
it 'returns the merge requests and issues links, with correct query' do
|
||||
get api("/projects/#{project.id}/releases", maintainer)
|
||||
|
||||
links = json_response.first['_links']
|
||||
release = json_response.first['tag_name']
|
||||
expected_query = "release_tag=#{release}&scope=all&state=opened"
|
||||
path_base = "/#{project.namespace.path}/#{project.path}"
|
||||
mr_uri = URI.parse(links['merge_requests_url'])
|
||||
issue_uri = URI.parse(links['issues_url'])
|
||||
|
||||
expect(mr_uri.path).to eq("#{path_base}/-/merge_requests")
|
||||
expect(issue_uri.path).to eq("#{path_base}/-/issues")
|
||||
expect(mr_uri.query).to eq(expected_query)
|
||||
expect(issue_uri.query).to eq(expected_query)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns an upcoming_release status for a future release' do
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ RSpec.describe Clusters::Applications::UninstallService, '#execute' do
|
|||
|
||||
context 'when there are no errors' do
|
||||
before do
|
||||
expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::DeleteCommand))
|
||||
expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand))
|
||||
allow(worker_class).to receive(:perform_in).and_return(nil)
|
||||
end
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ RSpec.describe Clusters::Applications::UninstallService, '#execute' do
|
|||
let(:error) { Kubeclient::HttpError.new(500, 'system failure', nil) }
|
||||
|
||||
before do
|
||||
expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::DeleteCommand)).and_raise(error)
|
||||
expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand)).and_raise(error)
|
||||
end
|
||||
|
||||
include_examples 'logs kubernetes errors' do
|
||||
|
|
@ -58,7 +58,7 @@ RSpec.describe Clusters::Applications::UninstallService, '#execute' do
|
|||
let(:error) { StandardError.new('something bad happened') }
|
||||
|
||||
before do
|
||||
expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::DeleteCommand)).and_raise(error)
|
||||
expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand)).and_raise(error)
|
||||
end
|
||||
|
||||
include_examples 'logs kubernetes errors' do
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@ RSpec.shared_examples 'helm command generator' do
|
|||
end
|
||||
|
||||
RSpec.shared_examples 'helm command' do
|
||||
describe 'HELM_VERSION' do
|
||||
subject { command.class::HELM_VERSION }
|
||||
|
||||
it { is_expected.to match(/\d+\.\d+\.\d+/) }
|
||||
end
|
||||
|
||||
describe '#env' do
|
||||
subject { command.env }
|
||||
|
||||
it { is_expected.to be_a Hash }
|
||||
end
|
||||
|
||||
describe '#rbac?' do
|
||||
subject { command.rbac? }
|
||||
|
||||
|
|
|
|||
|
|
@ -25,4 +25,21 @@ RSpec.shared_examples 'cluster application core specs' do |application_name|
|
|||
describe '.association_name' do
|
||||
it { expect(described_class.association_name).to eq(:"application_#{subject.name}") }
|
||||
end
|
||||
|
||||
describe '#helm_command_module' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:helm_major_version, :expected_helm_command_module) do
|
||||
2 | Gitlab::Kubernetes::Helm::V2
|
||||
3 | Gitlab::Kubernetes::Helm::V3
|
||||
end
|
||||
|
||||
with_them do
|
||||
subject { described_class.new(cluster: cluster).helm_command_module }
|
||||
|
||||
let(:cluster) { build(:cluster, helm_major_version: helm_major_version)}
|
||||
|
||||
it { is_expected.to eq(expected_helm_command_module) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ RSpec.shared_examples 'cluster application helm specs' do |application_name|
|
|||
describe '#uninstall_command' do
|
||||
subject { application.uninstall_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
|
||||
|
||||
it 'has files' do
|
||||
expect(subject.files).to eq(application.files)
|
||||
|
|
|
|||
Loading…
Reference in New Issue