The next intermediate state

This commit is contained in:
vic
2013-01-18 22:12:46 +04:00
parent 9c31719380
commit 5efecbd728
8 changed files with 73 additions and 115 deletions

View File

@@ -1,4 +1,3 @@
__author__ = 'vic'
#!/usr/bin/env python
import os, sys

View File

@@ -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)

View File

@@ -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()

View File

@@ -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')

View File

@@ -1,4 +1,4 @@
class IpNetworksPool:
class IpNetworksPool(object):
def __init__(self, networks, prefix):
self.networks = networks
self.prefix = prefix

View File

@@ -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')

View File

@@ -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()

View File

@@ -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):