The next intermediate state
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
__author__ = 'vic'
|
||||
#!/usr/bin/env python
|
||||
import os, sys
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class IpNetworksPool:
|
||||
class IpNetworksPool(object):
|
||||
def __init__(self, networks, prefix):
|
||||
self.networks = networks
|
||||
self.prefix = prefix
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
@@ -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):
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user