Skip to content

Commit

Permalink
feat: add m-capi-proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
mnaser committed Apr 10, 2023
1 parent 3348d36 commit a699349
Show file tree
Hide file tree
Showing 17 changed files with 3,523 additions and 147 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,40 @@ jobs:
- name: Build package
run: make build

install:
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
include:
- runs-on: ubuntu-20.04
openstack-version: yoga
python-version: "3.6"
- runs-on: ubuntu-latest
python-version: "3.8"
openstack-version: zed
- runs-on: ubuntu-latest
python-version: "3.8"
openstack-version: "2023.1"
steps:
- name: Checkout project
uses: actions/checkout@v3

- name: Install Poetry
run: pipx install poetry

- name: Setup Python
uses: actions/setup-python@v4
with:
cache: poetry
python-version: ${{ matrix.python-version }}

- name: Build package
run: make build

- name: Install package using constraints
run: pip install --constraint https://releases.openstack.org/constraints/upper/${{ matrix.openstack-version }} ./dist/*.whl

black:
runs-on: ubuntu-latest
steps:
Expand Down
8 changes: 8 additions & 0 deletions docs/labels.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@

Default value: `v1.25.3`

* `master_lb_floating_ip_enabled`

Attach a floating IP to the load balancer that fronts the Kubernetes API
servers. In order to disable this, you must be running the
`magnum-cluster-api-proxy` service on all your Neutron network nodes.

Default value: `true`

## OpenStack

* `fixed_subnet_cidr`
Expand Down
30 changes: 30 additions & 0 deletions magnum_cluster_api/cmd/proxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2023 VEXXHOST, Inc.
#
# 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 oslo_config import cfg
from oslo_log import log as logging

from magnum_cluster_api import service
from magnum_cluster_api.proxy import manager

CONF = cfg.CONF


def main():
logging.register_options(CONF)
logging.setup(CONF, "magnum-cluster-api-proxy")

server = service.Service(manager=manager.ProxyManager)
service.serve(server)
service.wait()
6 changes: 3 additions & 3 deletions magnum_cluster_api/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

import keystoneauth1
from magnum import objects as magnum_objects
from magnum.drivers.common import driver, k8s_monitor
from magnum.drivers.common import driver

from magnum_cluster_api import clients, objects, resources, utils
from magnum_cluster_api import clients, monitor, objects, resources, utils


class BaseDriver(driver.Driver):
Expand Down Expand Up @@ -261,7 +261,7 @@ def delete_nodegroup(self, context, cluster, nodegroup):
)

def get_monitor(self, context, cluster):
return k8s_monitor.K8sMonitor(context, cluster)
return monitor.Monitor(context, cluster)

# def rotate_ca_certificate(self, context, cluster):
# raise exception.NotSupported(
Expand Down
37 changes: 37 additions & 0 deletions magnum_cluster_api/monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (c) 2023 VEXXHOST, Inc.
#
# 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 magnum.conductor import k8s_api as k8s
from magnum.drivers.common import k8s_monitor
from oslo_log import log as logging

from magnum_cluster_api import utils

LOG = logging.getLogger(__name__)


class Monitor(k8s_monitor.K8sMonitor):
def poll_health_status(self):
# NOTE(mnaser): We override the `api_address` for the cluster if it's
# an isolated cluster so we can go through the proxy.
if utils.get_cluster_floating_ip_disabled(self.cluster):
api_address = f"https://{self.cluster.stack_id}.magnum-system:6443"
self.cluster.api_address = api_address
LOG.debug("Overriding cluster api_address to %s", api_address)

k8s_api = k8s.KubernetesAPI(self.context, self.cluster)
status, reason = self._poll_health_status(k8s_api)

self.data["health_status"] = status
self.data["health_status_reason"] = reason
12 changes: 12 additions & 0 deletions magnum_cluster_api/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
import pykube


class EndpointSlice(pykube.objects.NamespacedAPIObject):
version = "discovery.k8s.io/v1"
endpoint = "endpointslices"
kind = "EndpointSlice"


class ClusterResourceSet(pykube.objects.NamespacedAPIObject):
version = "addons.cluster.x-k8s.io/v1beta1"
endpoint = "clusterresourcesets"
Expand Down Expand Up @@ -63,6 +69,12 @@ class OpenStackClusterTemplate(pykube.objects.NamespacedAPIObject):
kind = "OpenStackClusterTemplate"


class OpenStackCluster(pykube.objects.NamespacedAPIObject):
version = "infrastructure.cluster.x-k8s.io/v1alpha6"
endpoint = "openstackclusters"
kind = "OpenStackCluster"


class ClusterClass(pykube.objects.NamespacedAPIObject):
version = "cluster.x-k8s.io/v1beta1"
endpoint = "clusterclasses"
Expand Down
22 changes: 22 additions & 0 deletions magnum_cluster_api/privsep/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) 2023 VEXXHOST, Inc.
#
# 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 oslo_privsep import capabilities, priv_context

haproxy_pctxt = priv_context.PrivContext(
__name__,
cfg_section="magnum_cluster_api_haproxy",
pypath=__name__ + ".haproxy_pctxt",
capabilities=[capabilities.CAP_NET_ADMIN],
)
47 changes: 47 additions & 0 deletions magnum_cluster_api/privsep/haproxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) 2023 VEXXHOST, Inc.
#
# 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.

import os
import signal
import subprocess

from oslo_log import log as logging

import magnum_cluster_api.privsep

LOG = logging.getLogger(__name__)


@magnum_cluster_api.privsep.haproxy_pctxt.entrypoint
def start(config_file):
proc = subprocess.Popen(["haproxy", "-f", config_file])

try:
retcode = proc.wait(timeout=5)
if retcode != 0:
LOG.error("HAproxy failed to start")
except subprocess.TimeoutExpired:
LOG.info("HAproxy started successfully")

return proc.pid


@magnum_cluster_api.privsep.haproxy_pctxt.entrypoint
def reload():
"""Reload HAproxy configuration"""

with open("/var/run/haproxy.pid", "r") as fd:
pid = int(fd.read().strip())

os.kill(pid, signal.SIGUSR2)
Loading

0 comments on commit a699349

Please sign in to comment.