Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add etcd ansible python plugin #1336

Merged
merged 5 commits into from
May 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ansible/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.pyc
*.so
*.test
*.out
*.retry

.idea/*
55 changes: 55 additions & 0 deletions ansible/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Ansible Action Plugin for VPP ETCD

This is a plugin that contains generated python files out of
.proto files. Ansible plugin uses them to parse and validate
json that we want to submit to etcd database. These files need
to be regenerated in case of changes in .proto files

## Prerequisites

protoc

### Install protoc

Install prerequisits for protoc:

apt-get install autoconf automake libtool curl make g++ unzip

1. download the protobuf-all\[VERSION\].tar.gz.
https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1
2. Extract the contents and change in the directory
3. Run following commands (This might take several minutes)

./configure
make
make check
sudo make install
sudo ldconfig # refresh shared library cache.

Check your installation:

protoc --version

Expect similar output to this:

libprotoc 3.6.1


### Use protoc to regenerate the python modules

Run [update_proto_classes.sh](../scripts/update_proto_classes.sh) script
to update automatically created python files if needed. This script will
generate python objects used with ansible plugin to pout directory that
will replace [pout](action_plugins/pout).

In case we need to use new .proto files they need to be added to the
[update_proto_classes.sh](../scripts/update_proto_classes.sh) script.
and python validation module needs to be written in a similar way as
[interface.py](action_plugins/plugins/interface.py)

### Usage example

First we need the etcd database to be started and running. Once it is running
we can start the [exmaple](example.yaml) ansible playbook with following command:

ansible-playbook example.yaml
13 changes: 13 additions & 0 deletions ansible/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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.
13 changes: 13 additions & 0 deletions ansible/action_plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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.
13 changes: 13 additions & 0 deletions ansible/action_plugins/plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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.
100 changes: 100 additions & 0 deletions ansible/action_plugins/plugins/bridgeDomain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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 json

import etcd3
from google.protobuf.json_format import MessageToJson, Parse

from action_plugins.pout.models.vpp.l2.bridge_domain_pb2 import BridgeDomain


def plugin_init(name, values, agent_name, ip, port):
if name == 'bridge-domain':
return BridgeDomainValidation(values, agent_name)
elif name == 'add-bridge-domain-interface':
return AddBridgeDomainInterfaceValidation(values, agent_name, ip, port)
elif name == 'remove-bridge-domain-interface':
return RemoveBridgeDomainInterfaceValidation(values, agent_name, ip, port)
else:
return False


class BridgeDomainValidation:

def __init__(self, values, agent_name):
self.values = values
self.agent_name = agent_name

def validate(self):
bridgeDomain = BridgeDomain()
Parse(json.dumps(self.values), bridgeDomain)
return MessageToJson(bridgeDomain, indent=None)

def create_key(self):
return "/vnf-agent/{}/config/vpp/l2/v2/bridge-domain/{}".format(self.agent_name, self.values['name'])


class AddBridgeDomainInterfaceValidation:

def __init__(self, values, agent_name, ip, port):
self.values = values
self.agent_name = agent_name
host = ip
port = port
self.client = etcd3.client(host, port)

def validate(self):
etcd_values = self.client.get(self.create_key())
val = {}
if etcd_values[0] is None:
val['interfaces'] = []
else:
val = json.loads(etcd_values[0])

if val.get('interfaces') is None:
val['interfaces'] = []
val['interfaces'] += self.values['interfaces']

bridgeDomain = BridgeDomain()
Parse(json.dumps(val), bridgeDomain)
return MessageToJson(bridgeDomain, indent=None)

def create_key(self):
return "/vnf-agent/{}/config/vpp/l2/v2/bridge-domain/{}".format(self.agent_name, self.values['name'])


class RemoveBridgeDomainInterfaceValidation:

def __init__(self, values, agent_name, ip, port):
self.values = values
self.agent_name = agent_name
host = ip
port = int(port)
self.client = etcd3.client(host, port)

def validate(self):
etcd_values = self.client.get(self.create_key())
val = json.loads(etcd_values[0])
try:
val['interfaces'].remove(self.values['interfaces'][0])
except:
pass

bridgeDomain = BridgeDomain()
Parse(json.dumps(val), bridgeDomain)
return MessageToJson(bridgeDomain, indent=None)

def create_key(self):
return "/vnf-agent/{}/config/vpp/l2/v2/bridge-domain/{}".format(self.agent_name, self.values['name'])
41 changes: 41 additions & 0 deletions ansible/action_plugins/plugins/interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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 json

from google.protobuf.json_format import MessageToJson, Parse

from action_plugins.pout.models.vpp.interfaces.interface_pb2 import Interface


def plugin_init(name, values, agent_name, ip ,port):
if name == 'interface':
return InterfaceValidation(values, agent_name)
else:
return False


class InterfaceValidation:

def __init__(self, values, agent_name):
self.values = values
self.agent_name =agent_name

def validate(self):
interface = Interface()
Parse(json.dumps(self.values), interface)
return MessageToJson(interface, indent=None)

def create_key(self):
return "/vnf-agent/{}/config/vpp/v2/interfaces/{}".format(self.agent_name, self.values['name'])
41 changes: 41 additions & 0 deletions ansible/action_plugins/plugins/nat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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 json

from google.protobuf.json_format import MessageToJson, Parse

from action_plugins.pout.models.vpp.nat.nat_pb2 import Nat44Global


def plugin_init(name, values, agent_name, ip, port):
if name == 'nat':
return NatValidation(values, agent_name)
else:
return False


class NatValidation:

def __init__(self, values, agent_name):
self.values = values
self.agent_name =agent_name

def validate(self):
nat = Nat44Global()
Parse(json.dumps(self.values), nat)
return MessageToJson(nat, indent=None)

def create_key(self):
return "/vnf-agent/{}/config/vpp/nat/v2/nat44-global".format(self.agent_name)
45 changes: 45 additions & 0 deletions ansible/action_plugins/plugins/route.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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 json
from enum import Enum

from google.protobuf.json_format import MessageToJson, Parse

from action_plugins.pout.models.vpp.l3.route_pb2 import Route


def plugin_init(name, values, agent_name, ip, port):
if name == 'route':
return RouteValidation(values, agent_name)
else:
return False


class RouteValidation:

def __init__(self, values, agent_name):
self.values = values
self.agent_name = agent_name

def validate(self):
route = Route()
Parse(json.dumps(self.values), route)
return MessageToJson(route, indent=None)

def create_key(self):
return "/vnf-agent/{}/config/vpp/v2/route/vrf/{}/dst/{}/gw/{}".format(self.agent_name,
self.values.get('name', 0),
self.values['dst_network'],
self.values.get('next_hop_addr', ''))
13 changes: 13 additions & 0 deletions ansible/action_plugins/pout/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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.
13 changes: 13 additions & 0 deletions ansible/action_plugins/pout/github/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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.
13 changes: 13 additions & 0 deletions ansible/action_plugins/pout/github/com/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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.
13 changes: 13 additions & 0 deletions ansible/action_plugins/pout/github/com/gogo/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) 2019 PANTHEON.tech
#
# 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.
Loading