From 5efecbd728390d29130d42c45ef898182a8a5cca Mon Sep 17 00:00:00 2001 From: vic Date: Fri, 18 Jan 2013 22:12:46 +0400 Subject: [PATCH] The next intermediate state --- src/devops.py | 1 - src/devops/{managers.py => api.py} | 40 +++++-------- src/devops/driver/libvirt/libvirt_driver.py | 13 ++-- .../driver/libvirt/libvirt_xml_builder.py | 11 ++-- src/devops/helpers/network.py | 2 +- src/devops/models.py | 59 ++++--------------- .../tests/{test_network.py => test_api.py} | 58 ++++++++++-------- src/devops/tests/test_models.py | 4 +- 8 files changed, 73 insertions(+), 115 deletions(-) rename src/devops/{managers.py => api.py} (52%) rename src/devops/tests/{test_network.py => test_api.py} (54%) diff --git a/src/devops.py b/src/devops.py index 9471c8cd..bfcea411 100644 --- a/src/devops.py +++ b/src/devops.py @@ -1,4 +1,3 @@ -__author__ = 'vic' #!/usr/bin/env python import os, sys diff --git a/src/devops/managers.py b/src/devops/api.py similarity index 52% rename from src/devops/managers.py rename to src/devops/api.py index cdd02e4f..adb63bf3 100644 --- a/src/devops/managers.py +++ b/src/devops/api.py @@ -1,28 +1,20 @@ import ipaddr from devops.helpers.helpers import generate_mac from devops.helpers.network import IpNetworksPool +from devops.models import Address, Interface, Node, Network, Environment __author__ = 'vic' -from django.db import models +class Api(object): - -class Manager(models.Manager): - - pass - -class EnvironmentManager(Manager): def create_environment(self, name): - return super(EnvironmentManager, self).create(name=name) + return Environment.objects.create(name=name) def list_environments(self): - return self.values('name') + return Environment.objects.values('name') def get_environment(self, name): - return super(EnvironmentManager, self).get(name=name) - - -class NetworkManager(models.Manager): + return Environment.objects.get(name=name) def create_network_pool(self, networks, prefix): return IpNetworksPool(networks=networks, prefix=prefix) @@ -34,34 +26,30 @@ class NetworkManager(models.Manager): self, name, environment=None, ip_network = None, pool=None, has_dhcp_server=False, has_pxe_server=False, forward='route'): allocated_network = ip_network or environment.allocate_network(pool or self._get_default_pool()) - return super(NetworkManager, self).create(environment=environment, name=name, ip_network=ip_network or allocated_network, has_pxe_server=has_pxe_server, has_dhcp_server=has_dhcp_server, forward=forward) - -class NodeManager(models.Manager): + return Network.objects.create(environment=environment, name=name, ip_network=ip_network or allocated_network, has_pxe_server=has_pxe_server, has_dhcp_server=has_dhcp_server, forward=forward) def create_node(self, name, environment=None, role=None, vcpu=1, memory=1024, has_vnc=True, metadata=None): - return super(NodeManager, self).create(name=name, environment=environment, role=role, vcpu=vcpu, memory=1024, has_vnc=has_vnc, metadata=None) + return Node.objects.create(name=name, environment=environment, role=role, vcpu=vcpu, memory=1024, has_vnc=has_vnc, metadata=None) -class DiskDeviceManager(models.Manager): - pass +#class DiskDeviceManager(models.Manager): +# pass -class VolumeManager(models.Manager): +#class VolumeManager(models.Manager): # def __init__(self, capacity=None, path=None, format='qcow2', base_image=None): - pass +# pass def upload(self, path): pass -class InterfaceManager(models.Manager): - allocate_ip = True + def _generate_mac(self): return generate_mac() def create_interface(self, network, node, type='network', target_dev=None, mac_address=None): - interface = super(InterfaceManager, self).create(network=network, node=node, type=type, target_dev=target_dev, mac_address=mac_address or self._generate_mac()) + interface = Interface.objects.create(network=network, node=node, type=type, target_dev=target_dev, mac_address=mac_address or self._generate_mac()) interface.add_address(str(network.next_ip())) return interface -class AddressManager(models.Manager): def create_address(self, ip_address, interface): - super(AddressManager, self).create(ip_address=ip_address, interface=interface) + Address.objects.create(ip_address=ip_address, interface=interface) diff --git a/src/devops/driver/libvirt/libvirt_driver.py b/src/devops/driver/libvirt/libvirt_driver.py index 3ff5cce5..9ed7e245 100644 --- a/src/devops/driver/libvirt/libvirt_driver.py +++ b/src/devops/driver/libvirt/libvirt_driver.py @@ -1,15 +1,15 @@ # vim: ts=4 sw=4 expandtab from time import sleep -import libvirt -from src.devops.driver.libvirt.libvirt_xml_builder import LibvirtXMLBuilder -from src.devops.helpers import scancodes -from src.devops.helpers.retry import retry +#import libvirt +from devops.driver.libvirt.libvirt_xml_builder import LibvirtXMLBuilder +from devops.helpers import scancodes +from devops.helpers.retry import retry import xml.etree.ElementTree as ET import ipaddr -from src.devops.models import Node, Volume -class LibvirtDriver: + +class LibvirtDriver(object): def __init__(self, connection_string="", xml_builder=LibvirtXMLBuilder()): self.xml_builder = xml_builder libvirt.virInitialize() @@ -28,6 +28,7 @@ class LibvirtDriver: @retry() def network_bridge_name(self, network): """ + :type network: Network :rtype : None """ self.conn.networkLookupByUUIDString(network.uuid).bridgeName() diff --git a/src/devops/driver/libvirt/libvirt_xml_builder.py b/src/devops/driver/libvirt/libvirt_xml_builder.py index 9b693af7..d680099f 100644 --- a/src/devops/driver/libvirt/libvirt_xml_builder.py +++ b/src/devops/driver/libvirt/libvirt_xml_builder.py @@ -1,14 +1,13 @@ from collections import deque from ipaddr import IPNetwork, IPAddress from xmlbuilder import XMLBuilder -from src.devops.models import Node, Volume, Network -class LibvirtXMLBuilder: +class LibvirtXMLBuilder(object): NAME_SIZE = 80 - def get_name(self, *args): + def _get_name(self, *args): name = '_'.join(list(args)) if len(name) > self.NAME_SIZE: hash_str = str(hash(name)) @@ -21,7 +20,7 @@ class LibvirtXMLBuilder: :rtype : String """ network_xml = XMLBuilder('network') - network_xml.name(self.get_name(network.environment and network.environment.name or '', network.name)) + network_xml.name(self._get_name(network.environment and network.environment.name or '', network.name)) if not (network.forward is None): network_xml.forward(mode=network.forward) if not (network.ip_network is None): @@ -54,7 +53,7 @@ class LibvirtXMLBuilder: :rtype : String """ volume_xml = XMLBuilder('volume') - volume_xml.name(self.get_name(volume.environment and volume.environment.name or '', volume.name)) + volume_xml.name(self._get_name(volume.environment and volume.environment.name or '', volume.name)) volume_xml.capacity(volume.capacity) with volume_xml.target: volume_xml.format(type=volume.format) @@ -93,7 +92,7 @@ class LibvirtXMLBuilder: :type node: Node """ node_xml = XMLBuilder("domain", type=node.hypervisor) - node_xml.name(self.get_name(node.environment and node.environment.name or '', node.name)) + node_xml.name(self._get_name(node.environment and node.environment.name or '', node.name)) node_xml.vcpu(str(node.vcpu)) node_xml.memory(str(node.memory), unit='MiB') diff --git a/src/devops/helpers/network.py b/src/devops/helpers/network.py index 562667a9..59f446f5 100644 --- a/src/devops/helpers/network.py +++ b/src/devops/helpers/network.py @@ -1,4 +1,4 @@ -class IpNetworksPool: +class IpNetworksPool(object): def __init__(self, networks, prefix): self.networks = networks self.prefix = prefix diff --git a/src/devops/models.py b/src/devops/models.py index 37d74460..c1ae4f6a 100644 --- a/src/devops/models.py +++ b/src/devops/models.py @@ -1,6 +1,5 @@ from ipaddr import IPNetwork -#from devops.driver.libvirt.libvirt_driver import LibvirtDriver -from devops.managers import EnvironmentManager, NodeManager, DiskDeviceManager, VolumeManager, AddressManager, NetworkManager, InterfaceManager +from devops.driver.libvirt.libvirt_driver import LibvirtDriver from django.db import models @@ -36,10 +35,10 @@ class ExternalModel(models.Model): name = models.CharField(max_length=255, unique=False, null=False) uuid = models.CharField(max_length=255) + #TODO constarint name env.manme class Environment(models.Model): name = models.CharField(max_length=255, unique=True, null=False) - objects = EnvironmentManager() # TODO find corresponded place @property @@ -49,18 +48,6 @@ class Environment(models.Model): """ return get_driver() - @property - def nodes(self): - return Node.objects.filter(environment=self) - - @property - def networks(self): - return Network.objects.filter(environment=self) - - @property - def volumes(self): - return Volume.objects.filter(environment=self) - def allocated_networks(self): return self.driver.get_allocated_networks() @@ -71,13 +58,13 @@ class Environment(models.Model): return ip_network def node_by_name(self, name): - self.nodes.filter(name=name) + return self.nodes.filter(name=name, environment=self) def nodes_by_role(self, role): - self.nodes.filter(role=role) + return self.nodes.filter(role=role, environment=self) def network_by_name(self, name): - self.networks.filter(name=name) + return self.networks.filter(name=name, environment=self) def define(self): for network in self.networks: @@ -86,7 +73,6 @@ class Environment(models.Model): volume.define() for node in self.nodes: node.define() - self.delete() def start(self): for network in self.networks: @@ -116,8 +102,7 @@ class Network(ExternalModel): tftp_root_dir = models.CharField(max_length=255) forward = choices('nat', 'route', 'bridge', 'private', 'vepa', 'passthrough', 'hostdev') ip_network = models.CharField(max_length=255, unique=True) - environment = models.ForeignKey(Environment, null=True) - objects = NetworkManager() + environment = models.ForeignKey(Environment, null=True, related_name='networks') @property def interfaces(self): @@ -168,16 +153,7 @@ class Node(ExternalModel): vcpu = models.PositiveSmallIntegerField(null=False, default=1) memory = models.IntegerField(null=False, default=1024) has_vnc = models.BooleanField(null=False, default=True) - environment = models.ForeignKey(Environment, null=True) - objects = NodeManager() - - @property - def disk_devices(self): - return DiskDevice.objects.filter(node=self) - - @property - def interfaces(self): - return Interface.objects.filter(node=self) + environment = models.ForeignKey(Environment, null=True, related_name='nodes') def interface_by_name(self, name): self.interfaces.filter(name=name) @@ -201,14 +177,13 @@ class DiskDevice(models.Model): type = choices('file') bus = choices('virtio') target_dev = models.CharField(max_length=255, null=False) - objects = DiskDeviceManager() + node = models.ForeignKey(Node, null=True, related_name='disk_devices') class Volume(ExternalModel): capacity = models.IntegerField(null=False) backing_store = models.ForeignKey('self', null=True) format = models.CharField(max_length=255, null=False) - environment = models.ForeignKey(Environment, null=True) - objects = VolumeManager() + environment = models.ForeignKey(Environment, null=True, related_name='volumes') @property def path(self): @@ -224,22 +199,14 @@ class Volume(ExternalModel): class Interface(models.Model): mac_address = models.CharField(max_length=255, unique=True, null=False) - network = models.ForeignKey(Network) - node = models.ForeignKey(Node) + network = models.ForeignKey(Network, related_name='interfaces') + node = models.ForeignKey(Node, related_name='interfaces') type = models.CharField(max_length=255, null=False) target_dev = models.CharField(max_length=255, unique=True, null=True) - objects = InterfaceManager() - - @property - def addresses(self): - return Address.objects.filter(interface=self) def add_address(self, address): - Address.objects.create_address(ip_address=address, interface=self) + Address.objects.create(ip_address=address, interface=self) class Address(models.Model): ip_address = models.GenericIPAddressField() - interface = models.ForeignKey(Interface) - objects = AddressManager() - - + interface = models.ForeignKey(Interface, related_name='addresses') diff --git a/src/devops/tests/test_network.py b/src/devops/tests/test_api.py similarity index 54% rename from src/devops/tests/test_network.py rename to src/devops/tests/test_api.py index 33874694..39930d0a 100644 --- a/src/devops/tests/test_network.py +++ b/src/devops/tests/test_api.py @@ -1,10 +1,12 @@ -import unittest +from django.test import TestCase from ipaddr import IPNetwork, IPv4Network from devops.helpers.network import IpNetworksPool -from devops.models import Network, Address, Interface, Node, Environment +from devops.api import Api -class TestIpNetworksPool(unittest.TestCase): +class TestIpNetworksPool(TestCase): + + api = Api() def test_getting_subnetworks(self): pool = IpNetworksPool(networks=[IPNetwork('10.1.0.0/22')], prefix=24) @@ -19,47 +21,51 @@ class TestIpNetworksPool(unittest.TestCase): self.assertEquals('10.1.0.254', str(IPv4Network('10.1.0.0/24')[-2])) def test_network_iterator(self): - environment = Environment.objects.create_environment('test_env') - network = Network.objects.create_network( + environment = self.api.create_environment('test_env') + node = self.api.create_node('test_node') + network = self.api.create_network( environment=environment, name='internal', ip_network='10.1.0.0/24') - node = Node.objects.create() - interface = Interface.objects.create_interface(network=network, node=node) - Address.objects.create_address(str('10.1.0.1'),interface=interface) + interface = self.api.create_interface(network=network, node=node) + self.api.create_address(str('10.1.0.1'),interface=interface) ip = network.next_ip() - Address.objects.create_address(str('10.1.0.3'),interface=interface) + self.api.create_address(str('10.1.0.3'),interface=interface) ip = network.next_ip() self.assertEquals('10.1.0.4', str(ip)) + def test_environment_values(self): + environment = self.api.create_environment('test_env') + print environment.volumes + def test_network_pool(self): - environment = Environment.objects.create_environment('test_env') - self.assertEqual('10.0.0.0/24', str(Network.objects.create_network( + environment = self.api.create_environment('test_env') + self.assertEqual('10.0.0.0/24', str(self.api.create_network( environment=environment, name='internal', pool=None).ip_network)) - self.assertEqual('10.0.1.0/24', str(Network.objects.create_network( + self.assertEqual('10.0.1.0/24', str(self.api.create_network( environment=environment, name='external', pool=None).ip_network)) - self.assertEqual('10.0.2.0/24', str(Network.objects.create_network( + self.assertEqual('10.0.2.0/24', str(self.api.create_network( environment=environment, name='private', pool=None).ip_network)) - environment = Environment.objects.create_environment('test_env2') - self.assertEqual('10.0.3.0/24', str(Network.objects.create_network( + environment = self.api.create_environment('test_env2') + self.assertEqual('10.0.3.0/24', str(self.api.create_network( environment=environment, name='internal', pool=None).ip_network)) - self.assertEqual('10.0.4.0/24', str(Network.objects.create_network( + self.assertEqual('10.0.4.0/24', str(self.api.create_network( environment=environment, name='external', pool=None).ip_network)) - self.assertEqual('10.0.5.0/24', str(Network.objects.create_network( + self.assertEqual('10.0.5.0/24', str(self.api.create_network( environment=environment, name='private', pool=None).ip_network)) def test_node_creation(self): - environment = Environment.objects.create_environment('test_env') - Network.objects.create_network( + environment = self.api.create_environment('test_env') + self.api.create_network( environment=environment, name='internal', pool=None) - Network.objects.create_network( + self.api.create_network( environment=environment, name='external', pool=None) - Network.objects.create_network( + self.api.create_network( environment=environment, name='private', pool=None) - environment = Environment.objects.create_environment('test_env2') - Network.objects.create_network( + environment = self.api.create_environment('test_env2') + self.api.create_network( environment=environment, name='internal', pool=None) - Network.objects.create_network( + self.api.create_network( environment=environment, name='external', pool=None) - Network.objects.create_network( + self.api.create_network( environment=environment, name='private', pool=None) - node = Node.objects.create_node('test_node') + node = self.api.create_node('test_node') node.define() diff --git a/src/devops/tests/test_models.py b/src/devops/tests/test_models.py index 385e1f1f..e5266ff0 100644 --- a/src/devops/tests/test_models.py +++ b/src/devops/tests/test_models.py @@ -1,9 +1,7 @@ from django.utils import unittest -from devops.models import choices, double_tuple +from devops.models import double_tuple -__author__ = 'vic' - class TestModels(unittest.TestCase):