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

Virtual PC and Firewall



Adds descriptors for the firewall
Updates Virtual PC to use two networks and adds more actions

Signed-off-by: default avatarbeierlm <mark.beierl@canonical.com>
parent cfd8ca33
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