Translate security group rules.

This commit handles the creation of security group rules out from k8s
network policies. It currently supports both egress and ingress rules.

Driver unit tests will be added in a follow-up patch as the driver
itself will still be modified in the series.

Partially-Implements: bp/k8s-network-policies
Change-Id: Ief415e3663cb9d46831291e15a06fca79d920ee9
Signed-off-by: Daniel Mellado <dmellado@redhat.com>
This commit is contained in:
Daniel Mellado 2018-08-16 05:26:02 -04:00
parent 974b8c2771
commit 0e95704e3d
2 changed files with 130 additions and 11 deletions

View File

@ -87,7 +87,53 @@ Testing the network policy support functionality
$ openstack security group list | grep test-network-policy
| dabdf308-7eed-43ef-a058-af84d1954acb | test-network-policy
4. Check that the teardown of the resources once the network policy is removed::
4. Check that the rules are in place for the security group::
$ kubectl get kuryrnetpolicy np-test-network-policy -o yaml
...
spec:
egressSgRules:
- security_group_rule:
created_at: 2018-09-19T06:15:07Z
description: Kuryr-Kubernetes egress SG rule
direction: egress
ethertype: IPv4
id: 93a3b0cc-611c-493b-9a28-0fb8517a50f1
port_range_max: 5978
port_range_min: 5978
project_id: c54246797a8b485389c406e8571539ef
protocol: tcp
...
security_group_id: 7f4f8003-5585-4231-9306-e5bdcc6d23df
tenant_id: c54246797a8b485389c406e8571539ef
updated_at: 2018-09-19T06:15:07Z
ingressSgRules:
- security_group_rule:
created_at: 2018-09-19T06:15:07Z
description: Kuryr-Kubernetes ingress SG rule
direction: ingress
ethertype: IPv4
id: 659b7d61-3a48-4c4a-8810-df20e4c1bfa2
port_range_max: 6379
port_range_min: 6379
project_id: c54246797a8b485389c406e8571539ef
protocol: tcp
...
security_group_id: 7f4f8003-5585-4231-9306-e5bdcc6d23df
tenant_id: c54246797a8b485389c406e8571539ef
updated_at: 2018-09-19T06:15:07Z
securityGroupId: 7f4f8003-5585-4231-9306-e5bdcc6d23df
securityGroupName: test-network-policy
$ openstack security group rule list test-network-policy --protocol tcp -c "IP Protocol" -c "Port Range" -c "Direction" --long
+-------------+------------+-----------+
| IP Protocol | Port Range | Direction |
+-------------+------------+-----------+
| tcp | 6379:6379 | ingress |
| tcp | 5978:5978 | egress |
+-------------+------------+-----------+
5. Confirm the teardown of the resources once the network policy is removed::
$ kubectl delete -f network_policy.yml

View File

@ -38,22 +38,87 @@ class NetworkPolicyDriver(base.NetworkPolicyDriver):
"security_group":
{
"name": policy['metadata']['name'],
"project_id": project_id
"project_id": project_id,
"description": "Kuryr-Kubernetes NetPolicy SG"
}
}
try:
sg = neutron.create_security_group(body=security_group_body)
i_rules, e_rules = self.apply_network_policy_rules(policy, sg)
except n_exc.NeutronClientException:
LOG.exception("Error creating security group for network policy. ")
raise
try:
self._add_kuryrnetpolicy_crd(policy, project_id,
sg['security_group']['id'])
sg['security_group']['id'], i_rules,
e_rules)
except exceptions.K8sClientException:
LOG.exception("Rolling back security groups")
neutron.delete_security_group(sg['security_group']['id'])
raise
def apply_network_policy_rules(self, policy, sg):
"""Creates and applies security group rules out of network policies.
Whenever a notification from the handler 'on-present' method is
received, security group rules are created out of network policies'
ingress and egress ports blocks.
"""
LOG.debug('Parsing Network Policy %s' % policy['metadata']['name'])
ingress_rule_list = policy['spec']['ingress']
egress_rule_list = policy['spec']['egress']
ingress_sg_rule_list = []
egress_sg_rule_list = []
for ingress_rule in ingress_rule_list:
LOG.debug('Parsing Ingress Rule %s' % ingress_rule)
if 'ports' in ingress_rule:
for port in ingress_rule['ports']:
i_rule = self._create_security_group_rule(
sg['security_group']['id'], 'ingress', port['port'],
protocol=port['protocol'].lower())
ingress_sg_rule_list.append(i_rule)
else:
LOG.debug('This network policy specifies no ingress ports')
for egress_rule in egress_rule_list:
LOG.debug('Parsing Egress Rule %s' % egress_rule)
if 'ports' in egress_rule:
for port in egress_rule['ports']:
e_rule = self._create_security_group_rule(
sg['security_group']['id'], 'egress', port['port'],
protocol=port['protocol'].lower())
egress_sg_rule_list.append(e_rule)
else:
LOG.debug('This network policy specifies no egress ports')
return ingress_sg_rule_list, egress_sg_rule_list
def _create_security_group_rule(
self, security_group_id, direction, port_range_min,
port_range_max=None, protocol='TCP', ethertype='IPv4',
description="Kuryr-Kubernetes NetPolicy SG rule"):
if not port_range_max:
port_range_max = port_range_min
security_group_rule_body = {
"security_group_rule": {
"ethertype": ethertype,
"security_group_id": security_group_id,
"description": description,
"direction": direction,
"protocol": protocol,
"port_range_min": port_range_min,
"port_range_max": port_range_max
}
}
LOG.debug("Creating sg rule %s" % security_group_rule_body)
neutron = clients.get_neutron_client()
try:
sg_rule = neutron.create_security_group_rule(
body=security_group_rule_body)
except n_exc.NeutronClientException:
LOG.exception("Error creating security group rule for the network "
"policy.")
raise
return sg_rule
def release_network_policy(self, policy, project_id):
neutron = clients.get_neutron_client()
netpolicy_crd = self._get_kuryrnetpolicy_crd(policy)
@ -85,30 +150,38 @@ class NetworkPolicyDriver(base.NetworkPolicyDriver):
raise
return netpolicy_crd
def _add_kuryrnetpolicy_crd(self, policy, project_id, sg_id):
def _add_kuryrnetpolicy_crd(self, policy, project_id, sg_id, i_rules,
e_rules):
kubernetes = clients.get_kubernetes_client()
netpolicy_crd_name = "np-" + policy['metadata']['name']
netpolicy_crd_namespace = policy['metadata']['namespace']
networkpolicy_name = policy['metadata']['name']
netpolicy_crd_name = "np-" + networkpolicy_name
namespace = policy['metadata']['namespace']
netpolicy_crd = {
'apiVersion': 'openstack.org/v1',
'kind': constants.K8S_OBJ_KURYRNETPOLICY,
'metadata': {
'name': netpolicy_crd_name,
'namespace': netpolicy_crd_namespace,
'namespace': namespace,
'annotations': {
'policy': policy
}
'networkpolicy_name': networkpolicy_name,
'networkpolicy_namespace': namespace,
'networkpolicy_uid': policy['metadata']['uid'],
'networkpolicy_spec': policy['spec']
},
},
'spec': {
'securityGroupName': policy['metadata']['name'],
'securityGroupName': "sg-" + networkpolicy_name,
'securityGroupId': sg_id,
'ingressSgRules': i_rules,
'egressSgRules': e_rules
},
}
try:
LOG.debug("Creating KuryrNetPolicy CRD %s" % netpolicy_crd)
kubernetes_post = '{}/{}/kuryrnetpolicies'.format(
constants.K8S_API_CRD_NAMESPACES,
netpolicy_crd_namespace)
namespace)
kubernetes.post(kubernetes_post, netpolicy_crd)
except exceptions.K8sClientException:
LOG.exception("Kubernetes Client Exception creating kuryrnetpolicy"