Commit f254c0b2 authored by Mark Beierl's avatar Mark Beierl
Browse files

Merge branch 'beierlm-hackfest' into 'master'

Virtual PC and Firewall

See merge request !133
parents cfd8ca33 c83576e0
Loading
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
# Vyos-config

This is a proxy charm used by Open Source Mano (OSM) to configure Vyos Router PNF, written in the [Python Operator Framwork](https://github.com/canonical/operator)
+43 −0
Original line number Diff line number Diff line
# VyOS Action
configure-remote:
  description: "Add firewall rule to VyOS PNF."
  params:
    magmaIP:
      description: "Magma AGW allowed IP"
      type: "string"
      default: "0.0.0.0"
  required:
    - magmaIP

backup:
  description: "Backup the current firewall configuration"
  params:
    backupFile:
      description: "Filename to store the backup into"
      type: "string"
      default: "backup.cfg"

restore:
  description: "Backup the current firewall configuration"
  params:
    backupFile:
      description: "Filename to restore the backup from"
      type: "string"
      default: "backup.cfg"

# Required by charms.osm.sshproxy
run:
  description: "Run an arbitrary command"
  params:
    command:
      description: "The command to execute."
      type: string
      default: ""
  required:
    - command
generate-ssh-key:
  description: "Generate a new SSH keypair for this unit. This will replace any existing previously generated keypair."
verify-ssh-credentials:
  description: "Verify that this unit can authenticate with server specified by ssh-hostname and ssh-username."
get-ssh-public-key:
  description: "Get the public SSH key for this unit."
+29 −0
Original line number Diff line number Diff line
options:
    ssh-hostname:
        type: string
        default: ""
        description: "The hostname or IP address of the machine to"
    ssh-username:
        type: string
        default: ""
        description: "The username to login as."
    ssh-password:
        type: string
        default: ""
        description: "The password used to authenticate."
    # ssh-private-key:
    #     type: string
    #     default: ""
    #     description: "DEPRECATED. The private ssh key to be used to authenticate."
    ssh-public-key:
        type: string
        default: ""
        description: "The public key of this unit."
    ssh-key-type:
        type: string
        default: "rsa"
        description: "The type of encryption to use for the SSH key."
    ssh-key-bits:
        type: int
        default: 4096
        description: "The number of bits to use for the SSH key."
+97 −0
Original line number Diff line number Diff line
#!/usr/bin/env python3
# Copyright 2020 Canonical Ltd.
#
# 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 sys

sys.path.append("lib")

from ops.charm import CharmBase, CharmEvents
from ops.framework import StoredState, EventBase, EventSource
from ops.main import main
from ops.model import (
    ActiveStatus,
    BlockedStatus,
    MaintenanceStatus,
    WaitingStatus,
    ModelError,
)
import os
import subprocess
import traceback

from charms.osm.sshproxy import SSHProxyCharm
from charms.osm import libansible


class VyosCharm(SSHProxyCharm):
    def __init__(self, framework, key):
        super().__init__(framework, key)

        # Register all of the events we want to observe
        self.framework.observe(self.on.config_changed, self.on_config_changed)
        self.framework.observe(self.on.install, self.on_install)
        self.framework.observe(self.on.start, self.on_start)
        self.framework.observe(self.on.upgrade_charm, self.on_upgrade_charm)
        # Charm actions (primitives)
        self.framework.observe(
            self.on.configure_remote_action, self.on_configure_remote_action
        )

    def on_config_changed(self, event):
        """Handle changes in configuration"""
        super().on_config_changed(event)

    def on_install(self, event):
        """Called when the charm is being installed"""
        super().on_install(event)
        self.unit.status = MaintenanceStatus("Installing Ansible")
        libansible.install_ansible_support()
        self.unit.status = ActiveStatus()

    def on_start(self, event):
        """Called when the charm is being started"""
        super().on_start(event)

    def on_configure_remote_action(self, event):
        """Configure remote."""

        if self.unit.is_leader():
            try:
                config = self.model.config
                magmaIP = event.params["magmaIP"]
                dict_vars = {"MAGMA_AGW_IP": magmaIP}
                result = libansible.execute_playbook(
                    "configure-remote.yaml",
                    config["ssh-hostname"],
                    config["ssh-username"],
                    config["ssh-password"],
                    dict_vars,
                )
                event.set_results({"output": result})
            except:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                err = traceback.format_exception(exc_type, exc_value, exc_traceback)
                event.fail(message="configure-remote failed: " + str(err))

        else:
            event.fail("Unit is not leader")
            return

    def on_upgrade_charm(self, event):
        """Upgrade the charm."""


if __name__ == "__main__":
    main(VyosCharm)
+97 −0
Original line number Diff line number Diff line
# Copyright 2014-2015 Canonical Limited.
#
# 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.

# Bootstrap charm-helpers, installing its dependencies if necessary using
# only standard libraries.
from __future__ import print_function
from __future__ import absolute_import

import functools
import inspect
import subprocess
import sys

try:
    import six  # NOQA:F401
except ImportError:
    if sys.version_info.major == 2:
        subprocess.check_call(['apt-get', 'install', '-y', 'python-six'])
    else:
        subprocess.check_call(['apt-get', 'install', '-y', 'python3-six'])
    import six  # NOQA:F401

try:
    import yaml  # NOQA:F401
except ImportError:
    if sys.version_info.major == 2:
        subprocess.check_call(['apt-get', 'install', '-y', 'python-yaml'])
    else:
        subprocess.check_call(['apt-get', 'install', '-y', 'python3-yaml'])
    import yaml  # NOQA:F401


# Holds a list of mapping of mangled function names that have been deprecated
# using the @deprecate decorator below.  This is so that the warning is only
# printed once for each usage of the function.
__deprecated_functions = {}


def deprecate(warning, date=None, log=None):
    """Add a deprecation warning the first time the function is used.
    The date, which is a string in semi-ISO8660 format indicate the year-month
    that the function is officially going to be removed.

    usage:

    @deprecate('use core/fetch/add_source() instead', '2017-04')
    def contributed_add_source_thing(...):
        ...

    And it then prints to the log ONCE that the function is deprecated.
    The reason for passing the logging function (log) is so that hookenv.log
    can be used for a charm if needed.

    :param warning:  String to indicat where it has moved ot.
    :param date: optional sting, in YYYY-MM format to indicate when the
                 function will definitely (probably) be removed.
    :param log: The log function to call to log.  If not, logs to stdout
    """
    def wrap(f):

        @functools.wraps(f)
        def wrapped_f(*args, **kwargs):
            try:
                module = inspect.getmodule(f)
                file = inspect.getsourcefile(f)
                lines = inspect.getsourcelines(f)
                f_name = "{}-{}-{}..{}-{}".format(
                    module.__name__, file, lines[0], lines[-1], f.__name__)
            except (IOError, TypeError):
                # assume it was local, so just use the name of the function
                f_name = f.__name__
            if f_name not in __deprecated_functions:
                __deprecated_functions[f_name] = True
                s = "DEPRECATION WARNING: Function {} is being removed".format(
                    f.__name__)
                if date:
                    s = "{} on/around {}".format(s, date)
                if warning:
                    s = "{} : {}".format(s, warning)
                if log:
                    log(s)
                else:
                    print(s)
            return f(*args, **kwargs)
        return wrapped_f
    return wrap
Loading