Commit bc3e63e3 authored by Sigmund Augdal's avatar Sigmund Augdal

Move securty groups related library code and tests from portal router_services repository

parent dd6277d7
import etcd
import socket
import logging
import uuid
RULE_KEYS = ("protocol", "source_type", "source_cidr", "source_security_group", "destination_port")
def security_group_key(group=None):
key = "nova/iaas/security_group"
if group:
key += "/" + str(group)
return key
def security_group_rule_key(group, rule=None):
key = security_group_key(group) + "/rules"
if rule:
key += "/" + str(rule)
return key
def get_group_name(etcd_client, group_id):
return etcd_client.get(security_group_key(group_id) + "/name").value
def create_security_group(etcd_client, name):
group_id = uuid.uuid4()
etcd_client.set(security_group_key(group_id) + "/name", name)
return group_id
def get_security_groups(etcd_client):
groups = {}
try:
for entry in etcd_client.list(security_group_key()):
if entry.dir:
group_id = entry.key.split("/")[-1]
try:
name = etcd_client.get(entry.key + "/name")
groups[group_id] = name.value
except etcd.EtcdError:
pass
except etcd.EtcdError:
pass
return groups
def get_group_rules(etcd_client, group_id):
group_key = security_group_key(group_id)
rules = []
try:
for entry in etcd_client.list(group_key + "/rules"):
if entry.dir:
rule = dict(id=entry.key.split("/")[-1])
for key in RULE_KEYS:
try:
rule[key] = etcd_client.get(entry.key + "/" + key).value
except etcd.EtcdError:
logging.exception("a")
pass
if "protocol" in rule and "source_type" in rule and "destination_port" in rule:
rules.append(rule)
except etcd.EtcdError:
logging.exception("b")
pass
rules.sort(key=lambda x: x['id'])
return rules
def add_rule(etcd_client, group_id, params):
rule_id = uuid.uuid4()
rule_key = security_group_rule_key(group_id, rule_id)
#validation
protocol = params["protocol"]
if protocol not in ("tcp", "udp"):
raise ValueError("invalid procol: " + protocol)
source_type = params["source_type"]
if source_type not in ("any", "cidr", "security_group"):
raise ValueError("invalid source type: " + source_type)
destination_port = int(params["destination_port"])
if destination_port <= 0 or destination_port > 0xffff:
raise ValueError("invalid destination port: {}".format(destination_port))
if source_type == "cidr":
source_net = params["source_net"]
source_mask = int(params["source_mask"])
if source_mask <= 0:
raise ValueError("invalid source mask: {}".format(source_mask))
try:
socket.inet_pton(socket.AF_INET, source_net)
if source_mask > 32:
raise ValueError("invalid source mask: {}".format(source_mask))
except socket.error:
try:
socket.inet_pton(socket.AF_INET6, source_net)
if source_mask > 128:
raise ValueError("invalid source mask: {}".format(source_mask))
except socket.error:
raise ValueError("Invalid source net: " + source_net)
elif source_type == "security_group":
source_security_group = params["source_security_group"]
try:
etcd_client.get(security_group_key(source_security_group) + "/name")
except etcd.EtcdError:
raise ValueError("Invalid source security group: " + source_security_group)
etcd_client.set(rule_key + "/protocol", protocol)
etcd_client.set(rule_key + "/source_type", source_type)
etcd_client.set(rule_key + "/destination_port", destination_port)
if source_type == "cidr":
etcd_client.set(rule_key + "/source_cidr", "{}/{}".format(source_net, source_mask))
elif source_type == "security_group":
etcd_client.set(rule_key + "/source_security_group", source_security_group)
def del_rule(etcd_client, group_id, rule_id):
rule_key = security_group_rule_key(group_id, rule_id)
for entry in etcd_client.list(rule_key):
etcd_client.delete(entry.key)
def get_group_members(etcd_client, group_id):
members_key = security_group_key(group_id) + "/members/by_mac"
try:
raw_members = etcd_client.get(members_key).value
except etcd.EtcdError as ex:
if ex.args[0] != 100:
raise ex
return "", []
members = raw_members.split("\n")
members = [m for m in members if m]
return raw_members, members
def get_groups_from_mac(etcd_client, mac):
groups = []
for group_id in get_security_groups(etcd_client):
_, members = get_group_members(etcd_client, group_id)
if mac in members:
groups.append(group_id)
return groups
def add_mac_to_group(etcd_client, group_id, mac):
members_key = security_group_key(group_id) + "/members/by_mac"
raw_members, members = get_group_members(etcd_client, group_id)
if mac in members:
return
members.append(mac)
new_members = "\n".join(members)
etcd_client.testandset(members_key, raw_members, new_members)
def delete_mac_from_group(etcd_client, group_id, mac):
members_key = security_group_key(group_id) + "/members/by_mac"
raw_members, members = get_group_members(etcd_client, group_id)
if not mac in members:
return
members.remove(mac)
new_members = "\n".join(members)
logging.debug("new members: %s", new_members)
if not new_members:
new_members = "\n"
etcd_client.testandset(members_key, raw_members, new_members)
This diff is collapsed.
import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
requires = [
'etcd-py>0.0.5',
'requests',
'python-daemon',
'pytest',
'mock',
]
setup(name='NovaRouterServices',
version='0.0',
description='Uninett nova router',
classifiers=[
"Programming Language :: Python",
],
packages=find_packages(),
include_package_data=True,
zip_safe=False,
install_requires=requires,
tests_require=requires,
dependency_links=[
'git+https://github.com/sigmunau/etcd-py.git#egg=etcd-py-0.0.6',
],
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment