summaryrefslogtreecommitdiff
path: root/lib/gitlab/kubernetes/cilium_network_policy.rb
blob: f77b3e8de99d56cc3c7395a3d8a6f0323d2e925d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# frozen_string_literal: true

module Gitlab
  module Kubernetes
    class CiliumNetworkPolicy
      include NetworkPolicyCommon
      extend ::Gitlab::Utils::Override

      API_VERSION = "cilium.io/v2"
      KIND = 'CiliumNetworkPolicy'

      # We are modeling existing kubernetes resource and don't have
      # control over amount of parameters.
      # rubocop:disable Metrics/ParameterLists
      def initialize(name:, namespace:, selector:, ingress:, resource_version: nil, description: nil, labels: nil, creation_timestamp: nil, egress: nil, annotations: nil)
        @name = name
        @description = description
        @namespace = namespace
        @labels = labels
        @creation_timestamp = creation_timestamp
        @selector = selector
        @resource_version = resource_version
        @ingress = ingress
        @egress = egress
        @annotations = annotations
      end
      # rubocop:enable Metrics/ParameterLists

      def self.from_yaml(manifest)
        return unless manifest

        policy = YAML.safe_load(manifest, symbolize_names: true)
        return if !policy[:metadata] || !policy[:spec]

        metadata = policy[:metadata]
        spec = policy[:spec]
        self.new(
          name: metadata[:name],
          description: policy[:description],
          namespace: metadata[:namespace],
          annotations: metadata[:annotations],
          resource_version: metadata[:resourceVersion],
          labels: metadata[:labels],
          selector: spec[:endpointSelector],
          ingress: spec[:ingress],
          egress: spec[:egress]
        )
      rescue Psych::SyntaxError, Psych::DisallowedClass
        nil
      end

      def self.from_resource(resource)
        return unless resource
        return if !resource[:metadata] || !resource[:spec]

        metadata = resource[:metadata]
        spec = resource[:spec].to_h
        self.new(
          name: metadata[:name],
          description: resource[:description],
          namespace: metadata[:namespace],
          annotations: metadata[:annotations]&.to_h,
          resource_version: metadata[:resourceVersion],
          labels: metadata[:labels]&.to_h,
          creation_timestamp: metadata[:creationTimestamp],
          selector: spec[:endpointSelector],
          ingress: spec[:ingress],
          egress: spec[:egress]
        )
      end

      override :resource
      def resource
        resource = {
          apiVersion: API_VERSION,
          kind: KIND,
          metadata: metadata,
          spec: spec
        }
        resource[:description] = description if description
        resource
      end

      private

      attr_reader :name, :description, :namespace, :labels, :creation_timestamp, :resource_version, :ingress, :egress, :annotations

      def selector
        @selector ||= {}
      end

      def metadata
        meta = { name: name, namespace: namespace }
        meta[:labels] = labels if labels
        meta[:resourceVersion] = resource_version if resource_version
        meta[:annotations] = annotations if annotations
        meta
      end

      def spec
        {
          endpointSelector: selector,
          ingress: ingress,
          egress: egress
        }.compact
      end
    end
  end
end