Files
kuryr-kubernetes/kuryr_kubernetes/controller/drivers/namespace_security_groups.py
Luis Tomas Bolivar 19580e32bb Improve LOG messaging
Changing exception logging by debug info. That is the expected
behavior when a pod is created right after creating the namespace
since the namespaces resources may take some time (seconds) to be
created. This ensures the user is not misled due to the
kuryr-controller logs.

Change-Id: Ie8c5e22741015a3417c7ab143d3c6dd0b4b8062d
2019-10-11 18:00:36 +02:00

183 lines
6.6 KiB
Python

# Copyright (c) 2018 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from kuryr.lib._i18n import _
from oslo_config import cfg
from oslo_log import log as logging
from kuryr_kubernetes import clients
from kuryr_kubernetes import config
from kuryr_kubernetes import constants
from kuryr_kubernetes.controller.drivers import base
from kuryr_kubernetes.controller.drivers import utils
from kuryr_kubernetes import exceptions
from neutronclient.common import exceptions as n_exc
LOG = logging.getLogger(__name__)
namespace_sg_driver_opts = [
cfg.StrOpt('sg_allow_from_namespaces',
help=_("Default security group to allow traffic from the "
"namespaces into the default namespace.")),
cfg.StrOpt('sg_allow_from_default',
help=_("Default security group to allow traffic from the "
"default namespaces into the other namespaces."))
]
cfg.CONF.register_opts(namespace_sg_driver_opts, "namespace_sg")
DEFAULT_NAMESPACE = 'default'
def _get_net_crd(namespace):
kubernetes = clients.get_kubernetes_client()
try:
ns = kubernetes.get('%s/namespaces/%s' % (constants.K8S_API_BASE,
namespace))
except exceptions.K8sClientException:
LOG.exception("Kubernetes Client Exception.")
raise exceptions.ResourceNotReady(namespace)
try:
annotations = ns['metadata']['annotations']
net_crd_name = annotations[constants.K8S_ANNOTATION_NET_CRD]
except KeyError:
LOG.debug("Namespace missing CRD annotations for selecting the "
"corresponding security group. Action will be retried.")
raise exceptions.ResourceNotReady(namespace)
try:
net_crd = kubernetes.get('%s/kuryrnets/%s' % (constants.K8S_API_CRD,
net_crd_name))
except exceptions.K8sClientException:
LOG.exception("Kubernetes Client Exception.")
raise
return net_crd
class NamespacePodSecurityGroupsDriver(base.PodSecurityGroupsDriver):
"""Provides security groups for Pod based on a configuration option."""
def get_security_groups(self, pod, project_id):
namespace = pod['metadata']['namespace']
net_crd = _get_net_crd(namespace)
sg_list = [str(net_crd['spec']['sgId'])]
extra_sgs = self._get_extra_sg(namespace)
for sg in extra_sgs:
sg_list.append(str(sg))
sg_list.extend(config.CONF.neutron_defaults.pod_security_groups)
return sg_list[:]
def _get_extra_sg(self, namespace):
# Differentiates between default namespace and the rest
if namespace == DEFAULT_NAMESPACE:
return [cfg.CONF.namespace_sg.sg_allow_from_namespaces]
else:
return [cfg.CONF.namespace_sg.sg_allow_from_default]
def create_namespace_sg(self, namespace, project_id, crd_spec):
neutron = clients.get_neutron_client()
sg_name = "ns/" + namespace + "-sg"
# create the associated SG for the namespace
try:
# default namespace is different from the rest
# Default allows traffic from everywhere
# The rest can be accessed from the default one
sg = neutron.create_security_group(
{
"security_group": {
"name": sg_name,
"project_id": project_id
}
}).get('security_group')
utils.tag_neutron_resources('security-groups', [sg['id']])
neutron.create_security_group_rule(
{
"security_group_rule": {
"direction": "ingress",
"remote_ip_prefix": crd_spec['subnetCIDR'],
"security_group_id": sg['id']
}
})
except n_exc.NeutronClientException:
LOG.exception("Error creating security group for the namespace "
"%s", namespace)
raise
return {'sgId': sg['id']}
def delete_sg(self, sg_id):
neutron = clients.get_neutron_client()
try:
neutron.delete_security_group(sg_id)
except n_exc.NotFound:
LOG.debug("Security Group not found: %s", sg_id)
except n_exc.NeutronClientException:
LOG.exception("Error deleting security group %s.", sg_id)
raise
def delete_namespace_sg_rules(self, namespace):
LOG.debug("Security group driver does not create SG rules for "
"namespace.")
def create_namespace_sg_rules(self, namespace):
LOG.debug("Security group driver does not create SG rules for "
"namespace.")
def update_namespace_sg_rules(self, namespace):
LOG.debug("Security group driver does not create SG rules for "
"namespace.")
def create_sg_rules(self, pod):
LOG.debug("Security group driver does not create SG rules for "
"the pods.")
def delete_sg_rules(self, pod):
LOG.debug("Security group driver does not delete SG rules for "
"the pods.")
def update_sg_rules(self, pod):
LOG.debug("Security group driver does not update SG rules for "
"the pods.")
class NamespaceServiceSecurityGroupsDriver(base.ServiceSecurityGroupsDriver):
"""Provides security groups for Service based on a configuration option."""
def get_security_groups(self, service, project_id):
namespace = service['metadata']['namespace']
net_crd = _get_net_crd(namespace)
sg_list = []
sg_list.append(str(net_crd['spec']['sgId']))
extra_sgs = self._get_extra_sg(namespace)
for sg in extra_sgs:
sg_list.append(str(sg))
return sg_list[:]
def _get_extra_sg(self, namespace):
# Differentiates between default namespace and the rest
if namespace == DEFAULT_NAMESPACE:
return [cfg.CONF.namespace_sg.sg_allow_from_default]
else:
return [cfg.CONF.namespace_sg.sg_allow_from_namespaces]