Support octavia-ingress-controller
- Add "octavia" as one of the "ingress_controller" options. - Add label "octavia_ingress_controller_tag". - Use external network ID in the heat templates. Story: 2004838 Change-Id: I7d889a054cd5feb2eeef523b20607a6c7630d777
This commit is contained in:
parent
f63761a804
commit
a941822c8e
@ -347,6 +347,8 @@ the table are linked to more details elsewhere in the user guide.
|
||||
+---------------------------------------+--------------------+---------------+
|
||||
| `ingress_controller_role`_ | see below | "ingress" |
|
||||
+---------------------------------------+--------------------+---------------+
|
||||
| `octavia_ingress_controller_tag`_ | see below | see below |
|
||||
+---------------------------------------+--------------------+---------------+
|
||||
| `kubelet_options`_ | extra kubelet args | "" |
|
||||
+---------------------------------------+--------------------+---------------+
|
||||
| `kubeapi_options`_ | extra kubeapi args | "" |
|
||||
@ -1235,8 +1237,11 @@ Magnum allows selecting one of multiple controller options via the
|
||||
your own Ingress resources.
|
||||
|
||||
_`ingress_controller`
|
||||
This label sets the Ingress Controller to be used. Currently only traefik
|
||||
is supported. The default is '', meaning no Ingress Controller configured.
|
||||
This label sets the Ingress Controller to be used. Currently 'traefik' and
|
||||
'octavia' are supported. The default is '', meaning no Ingress Controller
|
||||
configured. For more details about octavia-ingress-controller please refer
|
||||
to `cloud-provider-openstack document
|
||||
<https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-octavia-ingress-controller.md>`_
|
||||
|
||||
_`ingress_controller_role`
|
||||
This label defines the role nodes should have to run an instance of the
|
||||
@ -1247,6 +1252,11 @@ _`ingress_controller_role`
|
||||
|
||||
kubectl label node <node-name> role=ingress
|
||||
|
||||
This lable is not used for octavia-ingress-controller.
|
||||
|
||||
_`octavia_ingress_controller_tag`
|
||||
The image tag for octavia-ingress-controller. Stain-default: 1.13.2-alpha
|
||||
|
||||
DNS
|
||||
---
|
||||
|
||||
|
@ -53,3 +53,25 @@ def delete_floatingip(context, fix_port_id, cluster):
|
||||
except Exception as e:
|
||||
raise exception.PreDeletionFailed(cluster_uuid=cluster.uuid,
|
||||
msg=str(e))
|
||||
|
||||
|
||||
def get_network_id(context, network_name):
|
||||
nets = []
|
||||
n_client = clients.OpenStackClients(context).neutron()
|
||||
ext_filter = {'router:external': True}
|
||||
|
||||
networks = n_client.list_networks(**ext_filter)
|
||||
for net in networks.get('networks'):
|
||||
if net.get('name') == network_name:
|
||||
nets.append(net)
|
||||
|
||||
if len(nets) == 0:
|
||||
raise exception.ExternalNetworkNotFound(network=network_name)
|
||||
|
||||
if len(nets) > 1:
|
||||
raise exception.Conflict(
|
||||
"Multiple networks exist with same name '%s'. Please use the "
|
||||
"network ID instead." % network_name
|
||||
)
|
||||
|
||||
return nets[0]["id"]
|
||||
|
@ -3,9 +3,6 @@
|
||||
step="enable-ingress-controller"
|
||||
printf "Starting to run ${step}\n"
|
||||
|
||||
# Enables the specified ingress controller.
|
||||
#
|
||||
# Currently there is only support for traefik.
|
||||
. /etc/sysconfig/heat-params
|
||||
|
||||
function writeFile {
|
||||
@ -21,8 +18,20 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
if [ "$(echo $INGRESS_CONTROLLER | tr '[:upper:]' '[:lower:]')" = "traefik" ]; then
|
||||
ingress_controller=$(echo $INGRESS_CONTROLLER | tr '[:upper:]' '[:lower:]')
|
||||
case "$ingress_controller" in
|
||||
"")
|
||||
echo "No ingress controller configured."
|
||||
;;
|
||||
"traefik")
|
||||
$enable-ingress-traefik
|
||||
fi
|
||||
;;
|
||||
"octavia")
|
||||
$enable-ingress-octavia
|
||||
;;
|
||||
*)
|
||||
echo "Ingress controller $ingress_controller not supported."
|
||||
;;
|
||||
esac
|
||||
|
||||
printf "Finished running ${step}\n"
|
||||
|
@ -0,0 +1,122 @@
|
||||
# octavia-ingress-controller RBAC
|
||||
OCTAVIA_INGRESS_CONTROLLER_RBAC=/srv/magnum/kubernetes/manifests/octavia-ingress-controller-rbac.yaml
|
||||
OCTAVIA_INGRESS_CONTROLLER_RBAC_CONTENT=$(cat <<EOF
|
||||
---
|
||||
kind: ServiceAccount
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: octavia-ingress-controller
|
||||
namespace: kube-system
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: octavia-ingress-controller
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: octavia-ingress-controller
|
||||
namespace: kube-system
|
||||
EOF
|
||||
)
|
||||
writeFile $OCTAVIA_INGRESS_CONTROLLER_RBAC "$OCTAVIA_INGRESS_CONTROLLER_RBAC_CONTENT"
|
||||
|
||||
# octavia-ingress-controller config file
|
||||
OCTAVIA_INGRESS_CONTROLLER_CONFIGMAP=/srv/magnum/kubernetes/manifests/octavia-ingress-controller-config.yaml
|
||||
OCTAVIA_INGRESS_CONTROLLER_CONFIGMAP_CONTENT=$(cat <<EOF
|
||||
---
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: octavia-ingress-controller-config
|
||||
namespace: kube-system
|
||||
data:
|
||||
config: |
|
||||
cluster_name: ${CLUSTER_UUID}
|
||||
openstack:
|
||||
auth_url: ${AUTH_URL}
|
||||
user_id: ${TRUSTEE_USER_ID}
|
||||
password: ${TRUSTEE_PASSWORD}
|
||||
trust_id: ${TRUST_ID}
|
||||
region: ${REGION_NAME}
|
||||
ca_file: /etc/kubernetes/ca-bundle.crt
|
||||
octavia:
|
||||
subnet_id: ${CLUSTER_SUBNET}
|
||||
floating_network_id: ${EXTERNAL_NETWORK_ID}
|
||||
EOF
|
||||
)
|
||||
writeFile $OCTAVIA_INGRESS_CONTROLLER_CONFIGMAP "$OCTAVIA_INGRESS_CONTROLLER_CONFIGMAP_CONTENT"
|
||||
|
||||
# octavia-ingress-controller deployment
|
||||
oic_image="${CONTAINER_INFRA_PREFIX:-docker.io/k8scloudprovider/}octavia-ingress-controller:${OCTAVIA_INGRESS_CONTROLLER_TAG}"
|
||||
OCTAVIA_INGRESS_CONTROLLER=/srv/magnum/kubernetes/manifests/octavia-ingress-controller.yaml
|
||||
OCTAVIA_INGRESS_CONTROLLER_CONTENT=$(cat <<EOF
|
||||
---
|
||||
kind: StatefulSet
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: octavia-ingress-controller
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: octavia-ingress-controller
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: octavia-ingress-controller
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: octavia-ingress-controller
|
||||
spec:
|
||||
serviceAccountName: octavia-ingress-controller
|
||||
tolerations:
|
||||
- effect: NoSchedule # Make sure the pod can be scheduled on master kubelet.
|
||||
operator: Exists
|
||||
- key: CriticalAddonsOnly # Mark the pod as a critical add-on for rescheduling.
|
||||
operator: Exists
|
||||
- effect: NoExecute
|
||||
operator: Exists
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/master: "" # octavia-ingress-controller needs to access /etc/kubernetes folder.
|
||||
containers:
|
||||
- name: octavia-ingress-controller
|
||||
image: ${oic_image}
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- /bin/octavia-ingress-controller
|
||||
- --config=/etc/config/octavia-ingress-controller-config.yaml
|
||||
volumeMounts:
|
||||
- mountPath: /etc/kubernetes
|
||||
name: kubernetes-config
|
||||
readOnly: true
|
||||
- name: ingress-config
|
||||
mountPath: /etc/config
|
||||
hostNetwork: true
|
||||
volumes:
|
||||
- name: kubernetes-config
|
||||
hostPath:
|
||||
path: /etc/kubernetes
|
||||
type: Directory
|
||||
- name: ingress-config
|
||||
configMap:
|
||||
name: octavia-ingress-controller-config
|
||||
items:
|
||||
- key: config
|
||||
path: octavia-ingress-controller-config.yaml
|
||||
EOF
|
||||
)
|
||||
writeFile $OCTAVIA_INGRESS_CONTROLLER "$OCTAVIA_INGRESS_CONTROLLER_CONTENT"
|
||||
|
||||
echo "Waiting for Kubernetes API..."
|
||||
until [ "ok" = "$(curl --silent http://127.0.0.1:8080/healthz)" ]
|
||||
do
|
||||
sleep 5
|
||||
done
|
||||
|
||||
kubectl apply --validate=false -f $OCTAVIA_INGRESS_CONTROLLER_RBAC
|
||||
kubectl apply --validate=false -f $OCTAVIA_INGRESS_CONTROLLER_CONFIGMAP
|
||||
kubectl apply --validate=false -f $OCTAVIA_INGRESS_CONTROLLER
|
@ -67,6 +67,7 @@ write_files:
|
||||
CALICO_IPV4POOL="$CALICO_IPV4POOL"
|
||||
INGRESS_CONTROLLER="$INGRESS_CONTROLLER"
|
||||
INGRESS_CONTROLLER_ROLE="$INGRESS_CONTROLLER_ROLE"
|
||||
OCTAVIA_INGRESS_CONTROLLER_TAG="$OCTAVIA_INGRESS_CONTROLLER_TAG"
|
||||
KUBELET_OPTIONS="$KUBELET_OPTIONS"
|
||||
KUBECONTROLLER_OPTIONS="$KUBECONTROLLER_OPTIONS"
|
||||
KUBEAPI_OPTIONS="$KUBEAPI_OPTIONS"
|
||||
@ -81,3 +82,4 @@ write_files:
|
||||
KEYSTONE_AUTH_ENABLED="$KEYSTONE_AUTH_ENABLED"
|
||||
K8S_KEYSTONE_AUTH_TAG="$K8S_KEYSTONE_AUTH_TAG"
|
||||
PROJECT_ID="$PROJECT_ID"
|
||||
EXTERNAL_NETWORK_ID="$EXTERNAL_NETWORK_ID"
|
||||
|
@ -23,6 +23,7 @@ ca-file=/etc/kubernetes/ca-bundle.crt
|
||||
[LoadBalancer]
|
||||
use-octavia=$OCTAVIA_ENABLED
|
||||
subnet-id=$CLUSTER_SUBNET
|
||||
floating-network-id=$EXTERNAL_NETWORK_ID
|
||||
create-monitor=yes
|
||||
monitor-delay=1m
|
||||
monitor-timeout=30s
|
||||
|
@ -11,8 +11,11 @@
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from magnum.common import exception
|
||||
from magnum.common import keystone
|
||||
from magnum.common import neutron
|
||||
from magnum.drivers.heat import template_def
|
||||
|
||||
CONF = cfg.CONF
|
||||
@ -104,6 +107,17 @@ class K8sTemplateDefinition(template_def.BaseTemplateDefinition):
|
||||
|
||||
extra_params['octavia_enabled'] = keystone.is_octavia_enabled()
|
||||
|
||||
# NOTE(lxkong): Convert external network name to UUID, the template
|
||||
# field name is confused. If external_network_id is not specified in
|
||||
# cluster template use 'public' as the default value, which is the same
|
||||
# with the heat template default value as before.
|
||||
ext_net = cluster_template.external_network_id or "public"
|
||||
if not uuidutils.is_uuid_like(ext_net):
|
||||
ext_net_id = neutron.get_network_id(context, ext_net)
|
||||
extra_params['external_network'] = ext_net_id
|
||||
else:
|
||||
extra_params['external_network'] = ext_net
|
||||
|
||||
label_list = ['flannel_network_cidr', 'flannel_backend',
|
||||
'flannel_network_subnetlen',
|
||||
'system_pods_initial_delay',
|
||||
@ -114,8 +128,8 @@ class K8sTemplateDefinition(template_def.BaseTemplateDefinition):
|
||||
'kube_dashboard_enabled',
|
||||
'etcd_volume_size',
|
||||
'cert_manager_api',
|
||||
'ingress_controller',
|
||||
'ingress_controller_role',
|
||||
'octavia_ingress_controller_tag',
|
||||
'kubelet_options',
|
||||
'kubeapi_options',
|
||||
'kubeproxy_options',
|
||||
@ -126,6 +140,15 @@ class K8sTemplateDefinition(template_def.BaseTemplateDefinition):
|
||||
for label in label_list:
|
||||
extra_params[label] = cluster.labels.get(label)
|
||||
|
||||
ingress_controller = cluster.labels.get('ingress_controller',
|
||||
'').lower()
|
||||
if (ingress_controller == 'octavia'
|
||||
and not extra_params['octavia_enabled']):
|
||||
raise exception.InvalidParameterValue(
|
||||
'Octavia service needs to be deployed for octavia ingress '
|
||||
'controller.')
|
||||
extra_params["ingress_controller"] = ingress_controller
|
||||
|
||||
cluser_ip_range = cluster.labels.get('service_cluster_ip_range')
|
||||
if cluser_ip_range:
|
||||
extra_params['portal_network_cidr'] = cluser_ip_range
|
||||
|
@ -14,8 +14,7 @@ parameters:
|
||||
|
||||
external_network:
|
||||
type: string
|
||||
description: uuid/name of a network to use for floating ip addresses
|
||||
default: public
|
||||
description: uuid of a network to use for floating ip addresses
|
||||
|
||||
fixed_network:
|
||||
type: string
|
||||
@ -454,6 +453,11 @@ parameters:
|
||||
node role where the ingress controller backend should run
|
||||
default: "ingress"
|
||||
|
||||
octavia_ingress_controller_tag:
|
||||
type: string
|
||||
description: Octavia ingress controller docker image tag.
|
||||
default: "1.13.2-alpha"
|
||||
|
||||
kubelet_options:
|
||||
type: string
|
||||
description: >
|
||||
@ -754,6 +758,7 @@ resources:
|
||||
pods_network_cidr: {get_param: pods_network_cidr}
|
||||
ingress_controller: {get_param: ingress_controller}
|
||||
ingress_controller_role: {get_param: ingress_controller_role}
|
||||
octavia_ingress_controller_tag: {get_param: octavia_ingress_controller_tag}
|
||||
kubelet_options: {get_param: kubelet_options}
|
||||
kubeapi_options: {get_param: kubeapi_options}
|
||||
kubeproxy_options: {get_param: kubeproxy_options}
|
||||
@ -791,6 +796,7 @@ resources:
|
||||
- str_replace:
|
||||
params:
|
||||
$enable-ingress-traefik: {get_file: ../../common/templates/kubernetes/fragments/enable-ingress-traefik.sh}
|
||||
$enable-ingress-octavia: {get_file: ../../common/templates/kubernetes/fragments/enable-ingress-octavia.sh}
|
||||
template: {get_file: ../../common/templates/kubernetes/fragments/enable-ingress-controller.sh}
|
||||
- get_file: ../../common/templates/kubernetes/fragments/kube-dashboard-service.sh
|
||||
- get_file: ../../common/templates/kubernetes/fragments/enable-keystone-auth.sh
|
||||
|
@ -25,7 +25,7 @@ parameters:
|
||||
|
||||
external_network:
|
||||
type: string
|
||||
description: uuid/name of a network to use for floating ip addresses
|
||||
description: uuid of a network to use for floating ip addresses
|
||||
|
||||
portal_network_cidr:
|
||||
type: string
|
||||
@ -341,6 +341,10 @@ parameters:
|
||||
description: >
|
||||
node role where the ingress controller should run
|
||||
|
||||
octavia_ingress_controller_tag:
|
||||
type: string
|
||||
description: Octavia ingress controller docker image tag.
|
||||
|
||||
kubelet_options:
|
||||
type: string
|
||||
description: >
|
||||
@ -504,6 +508,7 @@ resources:
|
||||
"$CALICO_IPV4POOL": {get_param: calico_ipv4pool}
|
||||
"$INGRESS_CONTROLLER": {get_param: ingress_controller}
|
||||
"$INGRESS_CONTROLLER_ROLE": {get_param: ingress_controller_role}
|
||||
"$OCTAVIA_INGRESS_CONTROLLER_TAG": {get_param: octavia_ingress_controller_tag}
|
||||
"$KUBELET_OPTIONS": {get_param: kubelet_options}
|
||||
"$KUBEAPI_OPTIONS": {get_param: kubeapi_options}
|
||||
"$KUBECONTROLLER_OPTIONS": {get_param: kubecontroller_options}
|
||||
@ -518,6 +523,7 @@ resources:
|
||||
"$KEYSTONE_AUTH_ENABLED": {get_param: keystone_auth_enabled}
|
||||
"$K8S_KEYSTONE_AUTH_TAG": {get_param: k8s_keystone_auth_tag}
|
||||
"$PROJECT_ID": {get_param: project_id}
|
||||
"$EXTERNAL_NETWORK_ID": {get_param: external_network}
|
||||
|
||||
install_openstack_ca:
|
||||
type: OS::Heat::SoftwareConfig
|
||||
|
@ -136,3 +136,84 @@ class NeutronTest(base.TestCase):
|
||||
fake_port_id,
|
||||
self.cluster
|
||||
)
|
||||
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
def test_get_network_id(self, mock_clients):
|
||||
fake_name = "fake_network"
|
||||
fake_id = "24fe5da0-1ac0-11e9-84cd-00224d6b7bc1"
|
||||
mock_nclient = mock.MagicMock()
|
||||
mock_nclient.list_networks.return_value = {
|
||||
'networks': [
|
||||
{
|
||||
'id': fake_id,
|
||||
'name': fake_name,
|
||||
'router:external': True
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
osc = mock.MagicMock()
|
||||
mock_clients.return_value = osc
|
||||
osc.neutron.return_value = mock_nclient
|
||||
|
||||
network_id = neutron.get_network_id(self.context, fake_name)
|
||||
|
||||
self.assertEqual(fake_id, network_id)
|
||||
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
def test_get_network_id_notfound(self, mock_clients):
|
||||
fake_name = "fake_network"
|
||||
fake_id = "24fe5da0-1ac0-11e9-84cd-00224d6b7bc1"
|
||||
mock_nclient = mock.MagicMock()
|
||||
mock_nclient.list_networks.return_value = {
|
||||
'networks': [
|
||||
{
|
||||
'id': fake_id,
|
||||
'name': fake_name,
|
||||
'router:external': True
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
osc = mock.MagicMock()
|
||||
mock_clients.return_value = osc
|
||||
osc.neutron.return_value = mock_nclient
|
||||
|
||||
self.assertRaises(
|
||||
exception.ExternalNetworkNotFound,
|
||||
neutron.get_network_id,
|
||||
self.context,
|
||||
"another_network"
|
||||
)
|
||||
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
def test_get_network_id_conflict(self, mock_clients):
|
||||
fake_name = "fake_network"
|
||||
fake_id_1 = "24fe5da0-1ac0-11e9-84cd-00224d6b7bc1"
|
||||
fake_id_2 = "93781f82-1ac0-11e9-84cd-00224d6b7bc1"
|
||||
mock_nclient = mock.MagicMock()
|
||||
mock_nclient.list_networks.return_value = {
|
||||
'networks': [
|
||||
{
|
||||
'id': fake_id_1,
|
||||
'name': fake_name,
|
||||
'router:external': True
|
||||
},
|
||||
{
|
||||
'id': fake_id_2,
|
||||
'name': fake_name,
|
||||
'router:external': True
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
osc = mock.MagicMock()
|
||||
mock_clients.return_value = osc
|
||||
osc.neutron.return_value = mock_nclient
|
||||
|
||||
self.assertRaises(
|
||||
exception.Conflict,
|
||||
neutron.get_network_id,
|
||||
self.context,
|
||||
fake_name
|
||||
)
|
||||
|
@ -33,7 +33,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'master_flavor_id': 'master_flavor_id',
|
||||
'keypair_id': 'keypair_id',
|
||||
'dns_nameserver': 'dns_nameserver',
|
||||
'external_network_id': 'external_network_id',
|
||||
'external_network_id': 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e',
|
||||
'fixed_network': 'fixed_network',
|
||||
'fixed_subnet': 'fixed_subnet',
|
||||
'network_driver': 'network_driver',
|
||||
@ -232,7 +232,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
}
|
||||
expected = {
|
||||
'ssh_key_name': 'keypair_id',
|
||||
'external_network': 'external_network_id',
|
||||
'external_network': 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e',
|
||||
'fixed_network': 'fixed_network',
|
||||
'fixed_subnet': 'fixed_subnet',
|
||||
'network_driver': 'network_driver',
|
||||
@ -282,6 +282,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'cert_manager_api': 'False',
|
||||
'ingress_controller': 'i-controller',
|
||||
'ingress_controller_role': 'i-controller-role',
|
||||
'octavia_ingress_controller_tag': None,
|
||||
'kubelet_options': '--kubelet',
|
||||
'kubeapi_options': '--kubeapi',
|
||||
'kubecontroller_options': '--kubecontroller',
|
||||
@ -358,7 +359,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'docker_volume_size': 20,
|
||||
'docker_volume_type': 'lvmdriver-1',
|
||||
'etcd_volume_size': None,
|
||||
'external_network': 'external_network_id',
|
||||
'external_network': 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e',
|
||||
'fixed_network': 'fixed_network',
|
||||
'fixed_subnet': 'fixed_subnet',
|
||||
'flannel_backend': 'vxlan',
|
||||
@ -403,6 +404,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'cert_manager_api': 'False',
|
||||
'ingress_controller': 'i-controller',
|
||||
'ingress_controller_role': 'i-controller-role',
|
||||
'octavia_ingress_controller_tag': None,
|
||||
'kubelet_options': '--kubelet',
|
||||
'kubeapi_options': '--kubeapi',
|
||||
'kubecontroller_options': '--kubecontroller',
|
||||
@ -476,7 +478,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'docker_volume_size': 20,
|
||||
'master_flavor': 'master_flavor_id',
|
||||
'minion_flavor': 'flavor_id',
|
||||
'external_network': 'external_network_id',
|
||||
'external_network': 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e',
|
||||
'flannel_backend': 'vxlan',
|
||||
'flannel_network_cidr': '10.101.0.0/16',
|
||||
'flannel_network_subnetlen': '26',
|
||||
@ -511,6 +513,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'cert_manager_api': 'False',
|
||||
'ingress_controller': 'i-controller',
|
||||
'ingress_controller_role': 'i-controller-role',
|
||||
'octavia_ingress_controller_tag': None,
|
||||
'kubelet_options': '--kubelet',
|
||||
'kubeapi_options': '--kubeapi',
|
||||
'kubecontroller_options': '--kubecontroller',
|
||||
@ -561,7 +564,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
|
||||
expected = {
|
||||
'ssh_key_name': 'keypair_id',
|
||||
'external_network': 'external_network_id',
|
||||
'external_network': 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e',
|
||||
'fixed_network': 'fixed_network',
|
||||
'fixed_subnet': 'fixed_subnet',
|
||||
'availability_zone': 'az_1',
|
||||
@ -612,6 +615,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'cert_manager_api': 'False',
|
||||
'ingress_controller': 'i-controller',
|
||||
'ingress_controller_role': 'i-controller-role',
|
||||
'octavia_ingress_controller_tag': None,
|
||||
'kubelet_options': '--kubelet',
|
||||
'kubeapi_options': '--kubeapi',
|
||||
'kubecontroller_options': '--kubecontroller',
|
||||
@ -657,7 +661,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
expected = {
|
||||
'ssh_key_name': 'keypair_id',
|
||||
'availability_zone': 'az_1',
|
||||
'external_network': 'external_network_id',
|
||||
'external_network': 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e',
|
||||
'fixed_network': 'fixed_network',
|
||||
'fixed_subnet': 'fixed_subnet',
|
||||
'dns_nameserver': 'dns_nameserver',
|
||||
@ -707,6 +711,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'cert_manager_api': 'False',
|
||||
'ingress_controller': 'i-controller',
|
||||
'ingress_controller_role': 'i-controller-role',
|
||||
'octavia_ingress_controller_tag': None,
|
||||
'kubelet_options': '--kubelet',
|
||||
'kubeapi_options': '--kubeapi',
|
||||
'kubecontroller_options': '--kubecontroller',
|
||||
@ -896,7 +901,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
|
||||
expected = {
|
||||
'ssh_key_name': 'keypair_id',
|
||||
'external_network': 'external_network_id',
|
||||
'external_network': 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e',
|
||||
'fixed_network': 'fixed_network',
|
||||
'fixed_subnet': 'fixed_subnet',
|
||||
'dns_nameserver': 'dns_nameserver',
|
||||
@ -946,6 +951,7 @@ class TestClusterConductorWithK8s(base.TestCase):
|
||||
'cert_manager_api': 'False',
|
||||
'ingress_controller': 'i-controller',
|
||||
'ingress_controller_role': 'i-controller-role',
|
||||
'octavia_ingress_controller_tag': None,
|
||||
'kubelet_options': '--kubelet',
|
||||
'kubeapi_options': '--kubeapi',
|
||||
'kubecontroller_options': '--kubecontroller',
|
||||
|
@ -326,6 +326,8 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
mock_cluster_template.tls_disabled = False
|
||||
mock_cluster_template.registry_enabled = False
|
||||
mock_cluster_template.network_driver = 'flannel'
|
||||
external_network_id = '17e4e301-b7f3-4996-b3dd-97b3a700174b'
|
||||
mock_cluster_template.external_network_id = external_network_id
|
||||
mock_cluster = mock.MagicMock()
|
||||
mock_cluster.uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
|
||||
del mock_cluster.stack_id
|
||||
@ -384,9 +386,11 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
cgroup_driver = mock_cluster.labels.get(
|
||||
'cgroup_driver')
|
||||
ingress_controller = mock_cluster.labels.get(
|
||||
'ingress_controller')
|
||||
'ingress_controller').lower()
|
||||
ingress_controller_role = mock_cluster.labels.get(
|
||||
'ingress_controller_role')
|
||||
octavia_ingress_controller_tag = mock_cluster.labels.get(
|
||||
'octavia_ingress_controller_tag')
|
||||
kubelet_options = mock_cluster.labels.get(
|
||||
'kubelet_options')
|
||||
kubeapi_options = mock_cluster.labels.get(
|
||||
@ -459,6 +463,7 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
'pods_network_cidr': pods_network_cidr,
|
||||
'ingress_controller': ingress_controller,
|
||||
'ingress_controller_role': ingress_controller_role,
|
||||
'octavia_ingress_controller_tag': octavia_ingress_controller_tag,
|
||||
'octavia_enabled': False,
|
||||
'kube_service_account_key': 'public_key',
|
||||
'kube_service_account_private_key': 'private_key',
|
||||
@ -469,6 +474,7 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
'keystone_auth_enabled': keystone_auth_enabled,
|
||||
'k8s_keystone_auth_tag': k8s_keystone_auth_tag,
|
||||
'project_id': project_id,
|
||||
'external_network': external_network_id
|
||||
}}
|
||||
mock_get_params.assert_called_once_with(mock_context,
|
||||
mock_cluster_template,
|
||||
@ -486,6 +492,170 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
mock_cluster,
|
||||
)
|
||||
|
||||
@mock.patch('magnum.common.neutron.get_network_id')
|
||||
@mock.patch('magnum.common.keystone.is_octavia_enabled')
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
@mock.patch('magnum.drivers.k8s_fedora_atomic_v1.template_def'
|
||||
'.AtomicK8sTemplateDefinition.get_discovery_url')
|
||||
@mock.patch('magnum.drivers.heat.template_def.BaseTemplateDefinition'
|
||||
'.get_params')
|
||||
@mock.patch('magnum.drivers.heat.template_def.TemplateDefinition'
|
||||
'.get_output')
|
||||
@mock.patch('magnum.common.x509.operations.generate_csr_and_key')
|
||||
def test_k8s_get_params_external_network_id(self,
|
||||
mock_generate_csr_and_key,
|
||||
mock_get_output,
|
||||
mock_get_params,
|
||||
mock_get_discovery_url,
|
||||
mock_osc_class,
|
||||
mock_enable_octavia,
|
||||
mock_network_id):
|
||||
mock_generate_csr_and_key.return_value = {'csr': 'csr',
|
||||
'private_key': 'private_key',
|
||||
'public_key': 'public_key'}
|
||||
mock_enable_octavia.return_value = False
|
||||
mock_get_discovery_url.return_value = 'fake_discovery_url'
|
||||
external_network_id = 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e'
|
||||
mock_network_id.return_value = external_network_id
|
||||
|
||||
mock_context = mock.MagicMock()
|
||||
mock_context.auth_token = 'AUTH_TOKEN'
|
||||
mock_context.auth_url = 'http://192.168.10.10:5000/v3'
|
||||
mock_context.user_name = 'fake_user'
|
||||
|
||||
mock_cluster_template = mock.MagicMock()
|
||||
mock_cluster_template.tls_disabled = False
|
||||
mock_cluster_template.registry_enabled = False
|
||||
mock_cluster_template.network_driver = 'calico'
|
||||
mock_cluster_template.external_network_id = "public"
|
||||
|
||||
mock_cluster = mock.MagicMock()
|
||||
mock_cluster.labels = {}
|
||||
mock_cluster.uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
|
||||
|
||||
mock_osc = mock.MagicMock()
|
||||
mock_osc.magnum_url.return_value = 'http://127.0.0.1:9511/v1'
|
||||
mock_osc.cinder_region_name.return_value = 'RegionOne'
|
||||
mock_osc_class.return_value = mock_osc
|
||||
|
||||
k8s_def = k8sa_tdef.AtomicK8sTemplateDefinition()
|
||||
k8s_def.get_params(mock_context, mock_cluster_template, mock_cluster)
|
||||
|
||||
actual_params = mock_get_params.call_args[1]["extra_params"]
|
||||
self.assertEqual(
|
||||
external_network_id,
|
||||
actual_params.get("external_network")
|
||||
)
|
||||
mock_network_id.assert_called_once_with(
|
||||
mock_context,
|
||||
mock_cluster_template.external_network_id
|
||||
)
|
||||
|
||||
@mock.patch('magnum.common.keystone.is_octavia_enabled')
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
@mock.patch('magnum.drivers.k8s_fedora_atomic_v1.template_def'
|
||||
'.AtomicK8sTemplateDefinition.get_discovery_url')
|
||||
@mock.patch('magnum.drivers.heat.template_def.BaseTemplateDefinition'
|
||||
'.get_params')
|
||||
@mock.patch('magnum.drivers.heat.template_def.TemplateDefinition'
|
||||
'.get_output')
|
||||
@mock.patch('magnum.common.x509.operations.generate_csr_and_key')
|
||||
def test_k8s_get_params_octavia_disabled(self,
|
||||
mock_generate_csr_and_key,
|
||||
mock_get_output,
|
||||
mock_get_params,
|
||||
mock_get_discovery_url,
|
||||
mock_osc_class,
|
||||
mock_enable_octavia):
|
||||
mock_generate_csr_and_key.return_value = {'csr': 'csr',
|
||||
'private_key': 'private_key',
|
||||
'public_key': 'public_key'}
|
||||
mock_enable_octavia.return_value = False
|
||||
mock_get_discovery_url.return_value = 'fake_discovery_url'
|
||||
|
||||
mock_context = mock.MagicMock()
|
||||
mock_context.auth_token = 'AUTH_TOKEN'
|
||||
mock_context.auth_url = 'http://192.168.10.10:5000/v3'
|
||||
mock_context.user_name = 'fake_user'
|
||||
|
||||
mock_cluster_template = mock.MagicMock()
|
||||
mock_cluster_template.tls_disabled = False
|
||||
mock_cluster_template.registry_enabled = False
|
||||
mock_cluster_template.network_driver = 'calico'
|
||||
external_network_id = 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e'
|
||||
mock_cluster_template.external_network_id = external_network_id
|
||||
|
||||
mock_cluster = mock.MagicMock()
|
||||
mock_cluster.labels = {"ingress_controller": "octavia"}
|
||||
mock_cluster.uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
|
||||
|
||||
mock_osc = mock.MagicMock()
|
||||
mock_osc.magnum_url.return_value = 'http://127.0.0.1:9511/v1'
|
||||
mock_osc.cinder_region_name.return_value = 'RegionOne'
|
||||
mock_osc_class.return_value = mock_osc
|
||||
|
||||
k8s_def = k8sa_tdef.AtomicK8sTemplateDefinition()
|
||||
|
||||
self.assertRaises(
|
||||
exception.InvalidParameterValue,
|
||||
k8s_def.get_params,
|
||||
mock_context,
|
||||
mock_cluster_template,
|
||||
mock_cluster,
|
||||
)
|
||||
|
||||
@mock.patch('magnum.common.keystone.is_octavia_enabled')
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
@mock.patch('magnum.drivers.k8s_fedora_atomic_v1.template_def'
|
||||
'.AtomicK8sTemplateDefinition.get_discovery_url')
|
||||
@mock.patch('magnum.drivers.heat.template_def.BaseTemplateDefinition'
|
||||
'.get_params')
|
||||
@mock.patch('magnum.drivers.heat.template_def.TemplateDefinition'
|
||||
'.get_output')
|
||||
@mock.patch('magnum.common.x509.operations.generate_csr_and_key')
|
||||
def test_k8s_get_params_octavia_enabled(self,
|
||||
mock_generate_csr_and_key,
|
||||
mock_get_output,
|
||||
mock_get_params,
|
||||
mock_get_discovery_url,
|
||||
mock_osc_class,
|
||||
mock_enable_octavia):
|
||||
mock_generate_csr_and_key.return_value = {'csr': 'csr',
|
||||
'private_key': 'private_key',
|
||||
'public_key': 'public_key'}
|
||||
mock_enable_octavia.return_value = True
|
||||
mock_get_discovery_url.return_value = 'fake_discovery_url'
|
||||
|
||||
mock_context = mock.MagicMock()
|
||||
mock_context.auth_token = 'AUTH_TOKEN'
|
||||
mock_context.auth_url = 'http://192.168.10.10:5000/v3'
|
||||
mock_context.user_name = 'fake_user'
|
||||
|
||||
mock_cluster_template = mock.MagicMock()
|
||||
mock_cluster_template.tls_disabled = False
|
||||
mock_cluster_template.registry_enabled = False
|
||||
mock_cluster_template.network_driver = 'calico'
|
||||
external_network_id = 'e2a6c8b0-a3c2-42a3-b3f4-01400a30896e'
|
||||
mock_cluster_template.external_network_id = external_network_id
|
||||
|
||||
mock_cluster = mock.MagicMock()
|
||||
mock_cluster.labels = {"ingress_controller": "octavia"}
|
||||
mock_cluster.uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
|
||||
|
||||
mock_osc = mock.MagicMock()
|
||||
mock_osc.magnum_url.return_value = 'http://127.0.0.1:9511/v1'
|
||||
mock_osc.cinder_region_name.return_value = 'RegionOne'
|
||||
mock_osc_class.return_value = mock_osc
|
||||
|
||||
k8s_def = k8sa_tdef.AtomicK8sTemplateDefinition()
|
||||
k8s_def.get_params(mock_context, mock_cluster_template, mock_cluster)
|
||||
|
||||
actual_params = mock_get_params.call_args[1]["extra_params"]
|
||||
self.assertEqual(
|
||||
"octavia",
|
||||
actual_params.get("ingress_controller")
|
||||
)
|
||||
|
||||
@mock.patch('magnum.common.keystone.is_octavia_enabled')
|
||||
@mock.patch('magnum.common.clients.OpenStackClients')
|
||||
@mock.patch('magnum.drivers.heat.template_def'
|
||||
@ -513,6 +683,8 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
mock_cluster_template.tls_disabled = True
|
||||
mock_cluster_template.registry_enabled = False
|
||||
mock_cluster_template.network_driver = 'calico'
|
||||
external_network_id = '17e4e301-b7f3-4996-b3dd-97b3a700174b'
|
||||
mock_cluster_template.external_network_id = external_network_id
|
||||
mock_cluster = mock.MagicMock()
|
||||
mock_cluster.uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
|
||||
del mock_cluster.stack_id
|
||||
@ -571,9 +743,11 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
cgroup_driver = mock_cluster.labels.get(
|
||||
'cgroup_driver')
|
||||
ingress_controller = mock_cluster.labels.get(
|
||||
'ingress_controller')
|
||||
'ingress_controller').lower()
|
||||
ingress_controller_role = mock_cluster.labels.get(
|
||||
'ingress_controller_role')
|
||||
octavia_ingress_controller_tag = mock_cluster.labels.get(
|
||||
'octavia_ingress_controller_tag')
|
||||
kubelet_options = mock_cluster.labels.get(
|
||||
'kubelet_options')
|
||||
kubeapi_options = mock_cluster.labels.get(
|
||||
@ -648,6 +822,7 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
'pods_network_cidr': pods_network_cidr,
|
||||
'ingress_controller': ingress_controller,
|
||||
'ingress_controller_role': ingress_controller_role,
|
||||
'octavia_ingress_controller_tag': octavia_ingress_controller_tag,
|
||||
'octavia_enabled': False,
|
||||
'kube_service_account_key': 'public_key',
|
||||
'kube_service_account_private_key': 'private_key',
|
||||
@ -658,6 +833,7 @@ class AtomicK8sTemplateDefinitionTestCase(BaseK8sTemplateDefinitionTestCase):
|
||||
'keystone_auth_enabled': keystone_auth_enabled,
|
||||
'k8s_keystone_auth_tag': k8s_keystone_auth_tag,
|
||||
'project_id': project_id,
|
||||
'external_network': external_network_id
|
||||
}}
|
||||
mock_get_params.assert_called_once_with(mock_context,
|
||||
mock_cluster_template,
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add a new option 'octavia' for the label 'ingress_controller' and a new
|
||||
label 'octavia_ingress_controller_tag' to enable the deployment of
|
||||
`octavia-ingress-controller <https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-octavia-ingress-controller.md>`_
|
||||
in the kubernetes cluster. The 'ingress_controller_role' label is not used
|
||||
for this option.
|
Loading…
x
Reference in New Issue
Block a user