Commit ac2f5c1f authored by Zamir Martins Filho's avatar Zamir Martins Filho Committed by James Fargher

Add model for CiliumNetworkPolicy as a follow up of:

https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38003
parent 0fd3111d
---
title: Add model for CiliumNetworkPolicy
merge_request: 38848
author:
type: added
# frozen_string_literal: true
module Gitlab
module Kubernetes
class CiliumNetworkPolicy
include NetworkPolicyCommon
extend ::Gitlab::Utils::Override
API_VERSION = "cilium.io/v2"
KIND = 'CiliumNetworkPolicy'
def initialize(name:, namespace:, selector:, ingress:, resource_version:, labels: nil, creation_timestamp: nil, egress: nil)
@name = name
@namespace = namespace
@labels = labels
@creation_timestamp = creation_timestamp
@selector = selector
@resource_version = resource_version
@ingress = ingress
@egress = egress
end
def generate
::Kubeclient::Resource.new.tap do |resource|
resource.kind = KIND
resource.apiVersion = API_VERSION
resource.metadata = metadata
resource.spec = spec
end
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],
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],
namespace: metadata[:namespace],
resource_version: metadata[:resourceVersion],
labels: metadata[:labels]&.to_h,
creation_timestamp: metadata[:creationTimestamp],
selector: spec[:endpointSelector],
ingress: spec[:ingress],
egress: spec[:egress]
)
end
private
attr_reader :name, :namespace, :labels, :creation_timestamp, :resource_version, :ingress, :egress
def selector
@selector ||= {}
end
override :spec
def spec
{
endpointSelector: selector,
ingress: ingress,
egress: egress
}
end
end
end
end
...@@ -17,6 +17,13 @@ module Gitlab ...@@ -17,6 +17,13 @@ module Gitlab
@egress = egress @egress = egress
end end
def generate
::Kubeclient::Resource.new.tap do |resource|
resource.metadata = metadata
resource.spec = spec
end
end
def self.from_yaml(manifest) def self.from_yaml(manifest)
return unless manifest return unless manifest
......
...@@ -5,13 +5,6 @@ module Gitlab ...@@ -5,13 +5,6 @@ module Gitlab
module NetworkPolicyCommon module NetworkPolicyCommon
DISABLED_BY_LABEL = :'network-policy.gitlab.com/disabled_by' DISABLED_BY_LABEL = :'network-policy.gitlab.com/disabled_by'
def generate
::Kubeclient::Resource.new.tap do |resource|
resource.metadata = metadata
resource.spec = spec
end
end
def as_json(opts = nil) def as_json(opts = nil)
{ {
name: name, name: name,
...@@ -56,6 +49,7 @@ module Gitlab ...@@ -56,6 +49,7 @@ module Gitlab
def metadata def metadata
meta = { name: name, namespace: namespace } meta = { name: name, namespace: namespace }
meta[:labels] = labels if labels meta[:labels] = labels if labels
meta[:resourceVersion] = resource_version if defined?(resource_version)
meta meta
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Kubernetes::CiliumNetworkPolicy do
let(:policy) do
described_class.new(
name: name,
namespace: namespace,
creation_timestamp: '2020-04-14T00:08:30Z',
endpoint_selector: endpoint_selector,
ingress: ingress,
egress: egress,
description: description
)
end
let(:resource) do
::Kubeclient::Resource.new(
kind: partial_class_name,
apiVersion: "cilium.io/v2",
metadata: { name: name, namespace: namespace, resourceVersion: resource_version },
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: nil }
)
end
let(:name) { 'example-name' }
let(:namespace) { 'example-namespace' }
let(:endpoint_selector) { { matchLabels: { role: 'db' } } }
let(:description) { 'example-description' }
let(:partial_class_name) { described_class.name.split('::').last }
let(:resource_version) { 101 }
let(:ingress) do
[
{
fromEndpoints: [
{ matchLabels: { project: 'myproject' } }
]
}
]
end
let(:egress) do
[
{
ports: [{ port: 5978 }]
}
]
end
include_examples 'network policy common specs' do
let(:selector) { endpoint_selector}
let(:policy) do
described_class.new(
name: name,
namespace: namespace,
selector: selector,
ingress: ingress,
labels: labels,
resource_version: resource_version
)
end
let(:spec) { { endpointSelector: selector, ingress: ingress, egress: nil } }
let(:metadata) { { name: name, namespace: namespace, resourceVersion: resource_version } }
end
describe '#generate' do
subject { policy.generate }
it { is_expected.to eq(resource) }
end
describe '.from_yaml' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: example-name
namespace: example-namespace
resourceVersion: 101
spec:
endpointSelector:
matchLabels:
role: db
ingress:
- fromEndpoints:
- matchLabels:
project: myproject
POLICY
end
subject { Gitlab::Kubernetes::CiliumNetworkPolicy.from_yaml(manifest)&.generate }
it { is_expected.to eq(resource) }
context 'with nil manifest' do
let(:manifest) { nil }
it { is_expected.to be_nil }
end
context 'with invalid manifest' do
let(:manifest) { "\tfoo: bar" }
it { is_expected.to be_nil }
end
context 'with manifest without metadata' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
spec:
endpointSelector:
matchLabels:
role: db
ingress:
- fromEndpoints:
matchLabels:
project: myproject
POLICY
end
it { is_expected.to be_nil }
end
context 'with manifest without spec' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: example-name
namespace: example-namespace
POLICY
end
it { is_expected.to be_nil }
end
context 'with disallowed class' do
let(:manifest) do
<<~POLICY
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: example-name
namespace: example-namespace
creationTimestamp: 2020-04-14T00:08:30Z
spec:
endpointSelector:
matchLabels:
role: db
ingress:
- fromEndpoints:
matchLabels:
project: myproject
POLICY
end
it { is_expected.to be_nil }
end
end
describe '.from_resource' do
let(:resource) do
::Kubeclient::Resource.new(
metadata: {
name: name, namespace: namespace, creationTimestamp: '2020-04-14T00:08:30Z',
labels: { app: 'foo' }, resourceVersion: resource_version
},
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: nil, labels: nil, description: nil }
)
end
let(:generated_resource) do
::Kubeclient::Resource.new(
kind: partial_class_name,
apiVersion: "cilium.io/v2",
metadata: { name: name, namespace: namespace, resourceVersion: resource_version, labels: { app: 'foo' } },
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: nil }
)
end
subject { Gitlab::Kubernetes::CiliumNetworkPolicy.from_resource(resource)&.generate }
it { is_expected.to eq(generated_resource) }
context 'with nil resource' do
let(:resource) { nil }
it { is_expected.to be_nil }
end
context 'with resource without metadata' do
let(:resource) do
::Kubeclient::Resource.new(
spec: { endpointSelector: endpoint_selector, ingress: ingress, egress: nil, labels: nil, description: nil }
)
end
it { is_expected.to be_nil }
end
context 'with resource without spec' do
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: name, namespace: namespace, uid: '128cf288-7de4-11ea-aceb-42010a800089', resourceVersion: resource_version }
)
end
it { is_expected.to be_nil }
end
end
end
...@@ -15,6 +15,13 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do ...@@ -15,6 +15,13 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do
) )
end end
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: name, namespace: namespace },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
let(:name) { 'example-name' } let(:name) { 'example-name' }
let(:namespace) { 'example-namespace' } let(:namespace) { 'example-namespace' }
let(:pod_selector) { { matchLabels: { role: 'db' } } } let(:pod_selector) { { matchLabels: { role: 'db' } } }
...@@ -50,6 +57,13 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do ...@@ -50,6 +57,13 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do
end end
let(:spec) { { podSelector: selector, policyTypes: ["Ingress"], ingress: ingress, egress: nil } } let(:spec) { { podSelector: selector, policyTypes: ["Ingress"], ingress: ingress, egress: nil } }
let(:metadata) { { name: name, namespace: namespace } }
end
describe '#generate' do
subject { policy.generate }
it { is_expected.to eq(resource) }
end end
describe '.from_yaml' do describe '.from_yaml' do
...@@ -60,8 +74,6 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do ...@@ -60,8 +74,6 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do
metadata: metadata:
name: example-name name: example-name
namespace: example-namespace namespace: example-namespace
labels:
app: foo
spec: spec:
podSelector: podSelector:
matchLabels: matchLabels:
...@@ -76,13 +88,6 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do ...@@ -76,13 +88,6 @@ RSpec.describe Gitlab::Kubernetes::NetworkPolicy do
POLICY POLICY
end end
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: name, namespace: namespace, labels: { app: 'foo' } },
spec: { podSelector: pod_selector, policyTypes: %w(Ingress), ingress: ingress, egress: nil }
)
end
subject { Gitlab::Kubernetes::NetworkPolicy.from_yaml(manifest)&.generate } subject { Gitlab::Kubernetes::NetworkPolicy.from_yaml(manifest)&.generate }
it { is_expected.to eq(resource) } it { is_expected.to eq(resource) }
......
...@@ -5,19 +5,6 @@ RSpec.shared_examples 'network policy common specs' do ...@@ -5,19 +5,6 @@ RSpec.shared_examples 'network policy common specs' do
let(:namespace) { 'example-namespace' } let(:namespace) { 'example-namespace' }
let(:labels) { nil } let(:labels) { nil }
describe 'generate' do
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: name, namespace: namespace },
spec: spec
)
end
subject { policy.generate }
it { is_expected.to eq(resource) }
end
describe 'as_json' do describe 'as_json' do
let(:json_policy) do let(:json_policy) do
{ {
...@@ -26,7 +13,7 @@ RSpec.shared_examples 'network policy common specs' do ...@@ -26,7 +13,7 @@ RSpec.shared_examples 'network policy common specs' do
creation_timestamp: nil, creation_timestamp: nil,
manifest: YAML.dump( manifest: YAML.dump(
{ {
metadata: { name: name, namespace: namespace }, metadata: metadata,
spec: spec spec: spec
}.deep_stringify_keys }.deep_stringify_keys
), ),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment