diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
commit | 9f46488805e86b1bc341ea1620b866016c2ce5ed (patch) | |
tree | f9748c7e287041e37d6da49e0a29c9511dc34768 /lib/gitlab/kubernetes | |
parent | dfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff) | |
download | gitlab-ce-9f46488805e86b1bc341ea1620b866016c2ce5ed.tar.gz |
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'lib/gitlab/kubernetes')
-rw-r--r-- | lib/gitlab/kubernetes/helm.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/helm/api.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/helm/delete_command.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/helm/parsers/list_v2.rb | 37 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/kube_client.rb | 72 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/network_policy.rb | 91 |
6 files changed, 172 insertions, 38 deletions
diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb index 3e201d68297..00ab7109267 100644 --- a/lib/gitlab/kubernetes/helm.rb +++ b/lib/gitlab/kubernetes/helm.rb @@ -3,7 +3,7 @@ module Gitlab module Kubernetes module Helm - HELM_VERSION = '2.16.3' + HELM_VERSION = '2.16.6' KUBECTL_VERSION = '1.13.12' NAMESPACE = 'gitlab-managed-apps' NAMESPACE_LABELS = { 'app.gitlab.com/managed_by' => :gitlab }.freeze diff --git a/lib/gitlab/kubernetes/helm/api.rb b/lib/gitlab/kubernetes/helm/api.rb index 3b843799d66..ceda18442d6 100644 --- a/lib/gitlab/kubernetes/helm/api.rb +++ b/lib/gitlab/kubernetes/helm/api.rb @@ -99,11 +99,7 @@ module Gitlab command.cluster_role_binding_resource.tap do |cluster_role_binding_resource| break unless cluster_role_binding_resource - if cluster_role_binding_exists?(cluster_role_binding_resource) - kubeclient.update_cluster_role_binding(cluster_role_binding_resource) - else - kubeclient.create_cluster_role_binding(cluster_role_binding_resource) - end + kubeclient.update_cluster_role_binding(cluster_role_binding_resource) end end diff --git a/lib/gitlab/kubernetes/helm/delete_command.rb b/lib/gitlab/kubernetes/helm/delete_command.rb index 9d0fd30ba8f..771444ee9ee 100644 --- a/lib/gitlab/kubernetes/helm/delete_command.rb +++ b/lib/gitlab/kubernetes/helm/delete_command.rb @@ -36,8 +36,6 @@ module Gitlab @rbac end - private - def delete_command command = ['helm', 'delete', '--purge', name] + tls_flags_if_remote_tiller diff --git a/lib/gitlab/kubernetes/helm/parsers/list_v2.rb b/lib/gitlab/kubernetes/helm/parsers/list_v2.rb new file mode 100644 index 00000000000..c5c5d198a6c --- /dev/null +++ b/lib/gitlab/kubernetes/helm/parsers/list_v2.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Gitlab + module Kubernetes + module Helm + module Parsers + # Parses Helm v2 list (JSON) output + class ListV2 + ParserError = Class.new(StandardError) + + attr_reader :contents, :json + + def initialize(contents) + @contents = contents + @json = Gitlab::Json.parse(contents) + rescue JSON::ParserError => e + raise ParserError, e.message + end + + def releases + @releases = helm_releases + end + + private + + def helm_releases + helm_releases = json['Releases'] || [] + + raise ParserError, 'Invalid format for Releases' unless helm_releases.all? { |item| item.is_a?(Hash) } + + helm_releases + end + end + end + end + end +end diff --git a/lib/gitlab/kubernetes/kube_client.rb b/lib/gitlab/kubernetes/kube_client.rb index 7c5525b982c..2110d586d30 100644 --- a/lib/gitlab/kubernetes/kube_client.rb +++ b/lib/gitlab/kubernetes/kube_client.rb @@ -19,7 +19,9 @@ module Gitlab apps: { group: 'apis/apps', version: 'v1' }, extensions: { group: 'apis/extensions', version: 'v1beta1' }, istio: { group: 'apis/networking.istio.io', version: 'v1alpha3' }, - knative: { group: 'apis/serving.knative.dev', version: 'v1alpha1' } + knative: { group: 'apis/serving.knative.dev', version: 'v1alpha1' }, + metrics: { group: 'apis/metrics.k8s.io', version: 'v1beta1' }, + networking: { group: 'apis/networking.k8s.io', version: 'v1' } }.freeze SUPPORTED_API_GROUPS.each do |name, params| @@ -33,7 +35,8 @@ module Gitlab end # Core API methods delegates to the core api group client - delegate :get_pods, + delegate :get_nodes, + :get_pods, :get_secrets, :get_config_map, :get_namespace, @@ -56,9 +59,7 @@ module Gitlab # RBAC methods delegates to the apis/rbac.authorization.k8s.io api # group client - delegate :create_cluster_role_binding, - :get_cluster_role_binding, - :update_cluster_role_binding, + delegate :update_cluster_role_binding, to: :rbac_client # RBAC methods delegates to the apis/rbac.authorization.k8s.io api @@ -70,9 +71,7 @@ module Gitlab # RBAC methods delegates to the apis/rbac.authorization.k8s.io api # group client - delegate :create_role_binding, - :get_role_binding, - :update_role_binding, + delegate :update_role_binding, to: :rbac_client # non-entity methods that can only work with the core client @@ -88,6 +87,14 @@ module Gitlab :update_gateway, to: :istio_client + # NetworkPolicy methods delegate to the apis/networking.k8s.io api + # group client + delegate :create_network_policy, + :get_network_policies, + :update_network_policy, + :delete_network_policy, + to: :networking_client + attr_reader :api_prefix, :kubeclient_options DEFAULT_KUBECLIENT_OPTIONS = { @@ -97,6 +104,31 @@ module Gitlab } }.freeze + def self.graceful_request(cluster_id) + { status: :connected, response: yield } + rescue *Gitlab::Kubernetes::Errors::CONNECTION + { status: :unreachable } + rescue *Gitlab::Kubernetes::Errors::AUTHENTICATION + { status: :authentication_failure } + rescue Kubeclient::HttpError => e + { status: kubeclient_error_status(e.message) } + rescue => e + Gitlab::ErrorTracking.track_exception(e, cluster_id: cluster_id) + + { status: :unknown_failure } + end + + # KubeClient uses the same error class + # For connection errors (eg. timeout) and + # for Kubernetes errors. + def self.kubeclient_error_status(message) + if message&.match?(/timed out|timeout/i) + :unreachable + else + :authentication_failure + end + end + # We disable redirects through 'http_max_redirects: 0', # so that KubeClient does not follow redirects and # expose internal services. @@ -125,19 +157,11 @@ module Gitlab end def create_or_update_cluster_role_binding(resource) - if cluster_role_binding_exists?(resource) - update_cluster_role_binding(resource) - else - create_cluster_role_binding(resource) - end + update_cluster_role_binding(resource) end def create_or_update_role_binding(resource) - if role_binding_exists?(resource) - update_role_binding(resource) - else - create_role_binding(resource) - end + update_role_binding(resource) end def create_or_update_service_account(resource) @@ -164,18 +188,6 @@ module Gitlab Gitlab::UrlBlocker.validate!(api_prefix, allow_local_network: false) end - def cluster_role_binding_exists?(resource) - get_cluster_role_binding(resource.metadata.name) - rescue ::Kubeclient::ResourceNotFoundError - false - end - - def role_binding_exists?(resource) - get_role_binding(resource.metadata.name, resource.metadata.namespace) - rescue ::Kubeclient::ResourceNotFoundError - false - end - def service_account_exists?(resource) get_service_account(resource.metadata.name, resource.metadata.namespace) rescue ::Kubeclient::ResourceNotFoundError diff --git a/lib/gitlab/kubernetes/network_policy.rb b/lib/gitlab/kubernetes/network_policy.rb new file mode 100644 index 00000000000..ea25d81cbd2 --- /dev/null +++ b/lib/gitlab/kubernetes/network_policy.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +module Gitlab + module Kubernetes + class NetworkPolicy + def initialize(name:, namespace:, pod_selector:, ingress:, creation_timestamp: nil, policy_types: ["Ingress"], egress: nil) + @name = name + @namespace = namespace + @creation_timestamp = creation_timestamp + @pod_selector = pod_selector + @policy_types = policy_types + @ingress = ingress + @egress = egress + end + + def self.from_yaml(manifest) + return unless manifest + + policy = YAML.safe_load(manifest, symbolize_names: true) + return if !policy[:metadata] || !policy[:spec] + + metadata = policy[:metadata] + spec = policy[:spec] + self.new( + name: metadata[:name], + namespace: metadata[:namespace], + pod_selector: spec[:podSelector], + policy_types: spec[:policyTypes], + ingress: spec[:ingress], + egress: spec[:egress] + ) + rescue Psych::SyntaxError, Psych::DisallowedClass + nil + end + + def self.from_resource(resource) + return unless resource + return if !resource[:metadata] || !resource[:spec] + + metadata = resource[:metadata] + spec = resource[:spec].to_h + self.new( + name: metadata[:name], + namespace: metadata[:namespace], + creation_timestamp: metadata[:creationTimestamp], + pod_selector: spec[:podSelector], + policy_types: spec[:policyTypes], + ingress: spec[:ingress], + egress: spec[:egress] + ) + end + + def generate + ::Kubeclient::Resource.new.tap do |resource| + resource.metadata = metadata + resource.spec = spec + end + end + + def as_json(opts = nil) + { + name: name, + namespace: namespace, + creation_timestamp: creation_timestamp, + manifest: manifest + } + end + + private + + attr_reader :name, :namespace, :creation_timestamp, :pod_selector, :policy_types, :ingress, :egress + + def metadata + { name: name, namespace: namespace } + end + + def spec + { + podSelector: pod_selector, + policyTypes: policy_types, + ingress: ingress, + egress: egress + } + end + + def manifest + YAML.dump({ metadata: metadata, spec: spec }.deep_stringify_keys) + end + end + end +end |