예제 #1
0
class IncomingMachineRequest(ReadonlyContainer):
    implements(IIncomingMachineRequest)
    permissions(dict(hostname='read'))

    def __init__(self, hostname):
        self.__name__ = hostname
        self.hostname = hostname
class OpenVZContainer(ReadonlyContainer):
    permissions(dict(backend=('read', 'modify')))
    __name__ = 'openvz'
    __contains__ = IVirtualCompute

    @property
    def _items(self):
        # break an import cycle
        from opennode.oms.zodb import db
        machines = db.get_root()['oms_root']['machines']

        computes = {}

        def collect(container):
            from opennode.knot.model.machines import Machines

            seen = set()
            for item in container.listcontent():
                if ICompute.providedBy(item) and item.ctid is not None:
                    computes[str(item.ctid)] = Symlink(str(item.ctid), item)

                if (isinstance(item, Machines) or isinstance(item, Computes)
                        or ICompute.providedBy(item)
                        or IVirtualizationContainer.providedBy(item)):
                    if item.__name__ not in seen:
                        seen.add(item.__name__)
                        collect(item)

        collect(machines)
        return computes
예제 #3
0
class VncConsole(ReadonlyContainer):
    implements(IVncConsole, IGraphicalConsole)
    permissions(dict(hostname=('read', 'modify'),
                     port=('read', 'modify'),
                     ))

    proxy_processes = {}

    def __init__(self, hostname, port):
        self.inherit_permissions = True
        self.__name__ = 'vnc'
        self.hostname = hostname
        self.port = port

        self._ensure_proxy()

    def _ensure_proxy(self):
        if self.hostname in self.proxy_processes:
            # check if the proxy process has matching vnc port
            # otherwise kills it
            if self.proxy_processes[self.hostname].port != self.port:
                self.proxy_processes[self.hostname].kill()
                del self.proxy_processes[self.hostname]

        if self.hostname not in self.proxy_processes:
            self.proxy_processes[self.hostname] = VncProxyProcess(self.hostname, self.port)

    @property
    def ws_url(self):
        self._ensure_proxy()
        proxy_port = self.proxy_processes[self.hostname].proxy_port
        return 'ws://%s:%s/' % (self.hostname, proxy_port)
예제 #4
0
class OpenVzConsole(ReadonlyContainer):
    implements(IOpenVzConsole, ITextualConsole)
    permissions(dict(cid=('read', 'modify')))

    def __init__(self, name, cid):
        self.inherit_permissions = True
        self.__name__ = name
        self.cid = cid
예제 #5
0
class TtyConsole(ReadonlyContainer):
    implements(ITtyConsole, ITextualConsole)
    permissions(dict(pty=('read', 'modify')))

    def __init__(self, name, pty):
        self.inherit_permissions = True
        self.__name__ = name
        self.pty = pty
예제 #6
0
class SshConsole(ReadonlyContainer):
    implements(ISshConsole, ITextualConsole)
    permissions(dict(user=('read', 'modify'),
                     hostname=('read', 'modify'),
                     port=('read', 'modify'),
                     ))

    def __init__(self, name, user, hostname, port):
        self.inherit_permissions = True
        self.__name__ = name
        self.user = user
        self.hostname = hostname
        self.port = port
class VirtualizationContainer(Container):
    implements(IVirtualizationContainer, IInCompute, IInHangar)
    permissions(dict(backend=('read', 'modify')))

    __contains__ = IVirtualCompute

    def __init__(self, backend):
        super(VirtualizationContainer, self).__init__()
        self.backend = backend
        self.__name__ = 'vms-%s' % backend

    def __str__(self):
        return 'virtualizationcontainer-%s' % self.__name__

    def __repr__(self):
        return '<VirtualizationContainer backend=%s parent=%s id=0x%X>' % (
            self.__name__, self.__parent__, id(self))
class Compute(Container):
    """A compute node."""

    implements(ICompute, IDisplayName)
    permissions(dict(architecture='read', state='modify'))

    __contains__ = IInCompute

    _ipv4_address = u'0.0.0.0/32'
    ipv6_address = u'::/128'
    nameservers = []
    dns_domains = []

    type = 'unknown'  # XXX: how should this be determined?
    # and how do we differentiate for ONC physical and virtual computes?
    architecture = (u'x86_64', u'linux', u'centos')
    cpu_info = u"Intel Xeon 12.2GHz"
    disk_info = u"Seagate Barracuda SuperSaver 2000TB BuyNow!"
    memory_info = u"1333MHz DDR SuperGoodMemory!"

    os_release = u"build 35"
    kernel = u"2.6.18-238.9.1.el5.028stab089.1"

    num_cores = 1
    memory = 2048,
    network = 12.5 * M  # bytes
    diskspace = {
        u'total': 2000.0,
        u'root': 500.0,
        u'boot': 100.0,
        u'storage': 1000.0,
    }
    swap_size = 4192

    cpu_usage = (0.1, 0.11, 0.14)
    memory_usage = 773.2
    network_usage = (5.2 * M, 1.9 * M)
    diskspace_usage = {
        u'root': 249.0,
        u'boot': 49.3,
        u'storage': 748.3,
    }

    cpu_limit = 1.0

    autostart = False
    startup_timestamp = "2011-07-06 01:23:45"

    def __init__(self,
                 hostname,
                 state,
                 memory=None,
                 template=None,
                 ipv4_address=None):
        super(Compute, self).__init__()

        self.hostname = hostname
        self.memory = memory
        self.state = state
        self.template = template
        if ipv4_address:
            self._ipv4_address = ipv4_address

        #if self.template:
        #    alsoProvides(self, IVirtualCompute)
        #else:
        #    alsoProvides(self, IFuncInstalled)

        alsoProvides(self, IIncomplete)
        alsoProvides(self, IUndeployed)

        assert self.hostname

    def display_name(self):
        return self.hostname.encode('utf-8')

    @property
    def nicknames(self):
        """Returns all the nicknames of this Compute instance.

        Nicknames can be used to traverse to this object using
        alternative, potentially more convenient and/more memorable,
        names.

        """
        return [
            self.hostname,
        ]

    def get_effective_state(self):
        """Since we lack schema/data upgrade scripts I have to
        resort on this tricks to cope with the fact that I have
        existing objects around in the several test dbs, and branches.

        """
        return getattr(self, '_effective_state', unicode(self.state))

    def set_effective_state(self, value):
        self._effective_state = value

    effective_state = property(get_effective_state, set_effective_state)

    def __str__(self):
        return 'compute%s' % self.__name__

    def get_consoles(self):
        return None

    def set_consoles(self, value):
        pass

    consoles = property(get_consoles, set_consoles)

    @property
    def templates(self):
        return None

    def get_interfaces(self):
        return None

    def set_interfaces(self, value):
        pass

    interfaces = property(get_interfaces, set_interfaces)

    def get_routes(self):
        return None

    def set_routes(self, value):
        pass

    routes = property(get_routes, set_routes)

    @property
    def ipv4_address(self):
        if 'interfaces' not in self._items:
            return self._ipv4_address
        addresses = [
            i.ipv4_address for i in self._items['interfaces'] if i.ipv4_address
        ]
        if not addresses:
            return self._ipv4_address
        return unicode(addresses[0])
예제 #9
0
class UserProfile(Model):
    implements(IUserProfile, IDisplayName, IMarkable)
    permissions({
        'name': ('read', 'modify'),
        'groups': ('read', 'modify'),
        'credit': ('read', 'modify'),
        'balance_limit': ('read', 'modify'),
        'credit_timestamp': 'read',
        'uid': ('read', 'modify'),
        'vm_stats': ('read', 'modify'),
        'vm_stats_timestamp': 'read'
    })

    __name__ = None
    groups = []
    _credit = 0
    _balance_limit = 0
    _credit_timestamp = None
    _vm_stats_timestamp = None
    _vm_stats = {}
    uid = None

    def __init__(self,
                 name,
                 groups,
                 credit=0,
                 credit_timestamp='',
                 uid=None,
                 balance_limit=0):
        self.__name__ = name
        self.groups = groups
        self.credit = credit
        self.balance_limit = balance_limit
        self._credit_timestamp = credit_timestamp if credit_timestamp else self._credit_timestamp
        self.uid = uid
        self._vm_stats = {}
        self._vm_stats_timestamp = None

    def get_name(self):
        return self.__name__

    def set_name(self, value):
        self.__name__ = value

    name = property(get_name, set_name)

    @property
    def credit_timestamp(self):
        return self._credit_timestamp

    def set_credit(self, value):
        if type(value) in (int, long):
            self._credit = value
        elif type(value) is float:
            self._credit = int(value * 100)
        else:
            raise ValueError('credit must be integer or float!')

        self._credit_timestamp = datetime.now().isoformat()

    def get_credit(self):
        return self._credit

    credit = property(get_credit, set_credit)

    def set_vm_stats(self, stats):
        self._vm_stats = stats
        self._vm_stats_timestamp = datetime.now().isoformat()

    def get_vm_stats(self):
        return self._vm_stats

    vm_stats = property(get_vm_stats, set_vm_stats)

    @property
    def vm_stats_timestamp(self):
        return self._vm_stats_timestamp

    def set_balance_limit(self, value):
        if type(value) in (int, long):
            self._balance_limit = value
        elif type(value) is float:
            self._balance_limit = int(value * 100)
        else:
            raise ValueError('balance limit must be integer or float!')

    def get_balance_limit(self):
        return self._balance_limit

    balance_limit = property(get_balance_limit, set_balance_limit)

    def has_credit(self):
        return self.credit > 0 - self.balance_limit

    def display_name(self):
        return self.name

    def __repr__(self):
        return "UserProfile('%s', %s, %s, %s, '%s', %s)" % (
            self.__name__, self.groups, self.credit, self.balance_limit,
            self.credit_timestamp, self.uid)
예제 #10
0
class Compute(Container):
    """A compute node."""

    implements(ICompute, IDisplayName, IMarkable, IInVirtualizationContainer)

    permissions(dict(hostname=('read', 'modify'),
                     mac_addr=('read', 'modify'),
                     ipv4_address=('read', 'zope.Security'),
                     ipv6_address=('read', 'modify'),
                     nameservers=('read', 'modify'),
                     dns_domains=('read', 'modify'),
                     architecture=('read', 'modify'),
                     cpu_info=('read', 'modify'),
                     os_release=('read', 'modify'),
                     kernel=('read', 'modify'),
                     state=('read', 'modify'),
                     effective_state=('read', 'modify'),
                     num_cores=('read', 'modify'),
                     memory=('read', 'modify'),
                     diskspace=('read', 'modify'),
                     network=('read', 'modify'),
                     uptime=('read', 'modify'),
                     swap_size=('read', 'modify'),
                     cpu_usage=('read'),
                     memory_usage=('read'),
                     diskspace_usage=('read'),
                     network_usage=('read'),
                     cpu_limit=('read', 'modify'),
                     template=('read', 'modify'),
                     autostart=('read', 'modify'),
                     ctid=('read', 'modify'),
                     exclude_from_allocation=('read', 'modify'),
                     license_activated=('read', 'zope.Security')
                     ))

    __contains__ = IInCompute

    __markers__ = [IVirtualCompute, IDeployed, IUndeployed, IDeploying, IZabbixConfiguration, IManageable,
                   ISaltInstalled, IFuncInstalled, IAllocating]

    hostname = u''

    mac_address = None
    _ipv4_address = u'0.0.0.0/32'
    ipv6_address = u'::/128'
    nameservers = [u'8.8.8.8']
    dns_domains = []

    architecture = (u'x86_64', u'linux', u'centos')
    cpu_info = u"unknown"

    os_release = u"build 35"
    kernel = u"unknown"
    last_ping = False
    pingcheck = []
    suspicious = False
    failure = False

    num_cores = 1
    memory = 2048,
    network = 12.5 * M  # bytes
    diskspace = {
        u'total': 2000.0,
        u'/': 500.0,
        u'/boot': 100.0,
        u'/storage': 1000.0,
    }
    swap_size = 4192

    # empty values for metrics
    uptime = None
    cpu_usage = (0.0, 0.0, 0.0)
    memory_usage = 0.0
    network_usage = (0.0, 0.0)
    diskspace_usage = {
        u'root': 0.0,
        u'boot': 0.0,
        u'storage': 0.0,
    }

    cpu_limit = 1.0

    autostart = False

    # zabbix specific
    zabbix_hostgroups = []
    zabbix_dns_name = None
    zabbix_ipv4_address = None
    zabbix_use_dns = True
    zabbix_agent_port = 10050

    agent_version = u''

    exclude_from_allocation = False

    license_activated = True

    notify_admin = False

    def __init__(self, hostname, state=None, memory=None, template=None, ipv4_address=None, mgt_stack=None):
        super(Compute, self).__init__()

        self.hostname = hostname
        self.memory = memory
        self.state = state
        self.template = template
        if ipv4_address:
            self._ipv4_address = ipv4_address
        self._mgt_stack = mgt_stack

        if self.template:
            alsoProvides(self, IVirtualCompute)
            alsoProvides(self, IUndeployed)
        elif self._mgt_stack:
            alsoProvides(self, self._mgt_stack)

        assert self.hostname

    def display_name(self):
        return self.hostname.encode('utf-8')

    @property
    def nicknames(self):
        """Returns all the nicknames of this Compute instance.

        Nicknames can be used to traverse to this object using
        alternative, potentially more convenient and/more memorable,
        names.

        """
        return [self.hostname, ]

    @property
    def effective_state(self):
        """Since we lack schema/data upgrade scripts I have to
        resort on this tricks to cope with the fact that I have
        existing objects around in the several test dbs, and branches.

        """
        return getattr(self, '_effective_state', unicode(self.state))

    def get_ctid(self):
        return getattr(self, '_ctid', None)

    def set_ctid(self, value):
        self._ctid = int(value) if value is not None else None

    ctid = property(get_ctid, set_ctid)

    def __str__(self):
        return 'compute%s' % self.__name__

    def get_consoles(self):
        if 'consoles' not in self._items:
            self._add(Consoles())
        return self._items['consoles']

    def set_consoles(self, value):
        if 'consoles' in self._items:
            del self._items['consoles']
        self._add(value)

    consoles = property(get_consoles, set_consoles)

    @property
    def templates(self):
        from opennode.oms.zodb import db

        @db.assert_transact
        def do_it():
            if not self['templates']:
                templates = Templates()
                templates.__name__ = 'templates'
                self._add(templates)
            return self['templates']
        return do_it()

    def get_interfaces(self):
        if 'interfaces' not in self._items:
            self._add(NetworkInterfaces())
        return self._items['interfaces']

    def set_interfaces(self, value):
        if 'interfaces' in self._items:
            del self._items['interfaces']
        self._add(value)

    interfaces = property(get_interfaces, set_interfaces)

    def get_routes(self):
        if 'routes' not in self._items:
            self._add(NetworkRoutes())
        return self._items['routes']

    def set_routes(self, value):
        if 'routes' in self._items:
            del self._items['routes']
        self._add(value)

    routes = property(get_routes, set_routes)

    def get_ipv4_address(self):
        if 'interfaces' not in self._items:
            return self._ipv4_address

        primaries = [i.ipv4_address for i in self._items['interfaces']
                     if i.ipv4_address and getattr(i, 'primary', False)]

        if primaries:
            return unicode(primaries[0])

        # No interface has been marked as primary, so let's just pick one
        addresses = [i.ipv4_address for i in self._items['interfaces'] if i.ipv4_address]
        if not addresses:
            return self._ipv4_address
        return unicode(addresses[0])

    @require_admins
    def set_ipv4_address_fallback(self, value):
        """ Sets the fallback value of the IP address """
        self._ipv4_address = value

    ipv4_address = property(get_ipv4_address, set_ipv4_address_fallback)

    def __repr__(self):
        return '<Compute %s>' % self.__name__

    def set_owner(self, principal):
        super(Compute, self).set_owner(principal)
        log.info('%s changed owner to: %s', self.__name__, principal)
예제 #11
0
class ReadonlyContainer(Model):
    """A container whose items cannot be modified, i.e. are predefined."""
    implements(IContainer)
    permissions(
        dict(
            listnames='traverse',
            listcontent='traverse',
            __iter__='traverse',
            __getitem__='traverse',
            can_contain='add',
            content='traverse',
            add='add',
        ))

    def __getitem__(self, key):
        return self.content().get(key)

    def listnames(self):
        return self.content().keys()

    def listcontent(self):
        return self.content().values()

    def __iter__(self):
        return iter(self.listcontent())

    def can_contain(self, item):
        """A read only container cannot accept new children"""
        return False

    @exception_logger
    def content(self):
        injectors = querySubscriptions(self, IContainerInjector)
        for injector in injectors:
            interface_filter = getattr(injector, '__interfaces__', [])
            if interface_filter and not any(
                    map(lambda i: i.providedBy(self), interface_filter)):
                continue

            for k, v in injector.inject().items():
                if k not in self._items:
                    v.__parent__ = self
                    self._items[k] = v

        items = dict(**self._items)

        extenders = querySubscriptions(self, IContainerExtender)
        for extender in extenders:
            interface_filter = getattr(extender, '__interfaces__', [])
            if interface_filter and not any(
                    map(lambda i: i.providedBy(self), interface_filter)):
                continue

            children = extender.extend()
            for v in children.values():
                v.__parent__ = self
                v.__transient__ = True
                v.inherit_permissions = True
            items.update(children)

        return items

    _items = {}
예제 #12
0
class Model(persistent.Persistent):

    implements(IModel, IAttributeAnnotatable, ITimestamp)
    permissions(dict(__name__='view'))

    __parent__ = None
    __name__ = None

    __transient__ = False

    _inherit_permissions = False

    _ctime = None
    _mtime = None
    _mtime_blacklist = ('inherit_permissions', 'owner', 'features', 'oid',
                        'metadata')

    def __init__(self, *args, **kwargs):
        self._ctime = self._mtime = time.time()
        super(Model, self).__init__(self, *args, **kwargs)

    @property
    def ctime(self):
        if self._ctime is None:
            self._ctime = time.time()
        return self._ctime

    @property
    def mtime(self):
        if self._mtime is None:
            self._mtime = time.time()
        return self._mtime

    def _p_resolveConflict(self, oldState, savedState, newState):
        logger.debug('Resolve conflict: %s -> %s -> %s, choosing last',
                     oldState, savedState, newState)
        return newState

    def set_inherit_permissions(self, value):
        self._inherit_permissions = value

    def get_inherit_permissions(self):
        return self._inherit_permissions or self.__transient__

    inherit_permissions = property(get_inherit_permissions,
                                   set_inherit_permissions)

    def set_owner(self, principal):
        prinrole = interfaces.IPrincipalRoleManager(self)
        oldowner = self.__owner__
        prinrole.unsetRoleForPrincipal('owner', oldowner)
        prinrole.assignRoleToPrincipal('owner', principal.id)

        if (not hasattr(self, '__suppress_events') and principal is not None
                and principal.id != oldowner):
            handle(self, OwnerChangedEvent(oldowner, principal.id))

    def get_owner(self):
        prinrole = interfaces.IPrincipalRoleManager(self)
        owners = prinrole.getPrincipalsForRole('owner')
        owners = map(lambda p: p[0],
                     filter(lambda p: p[1].getName() == 'Allow', owners))
        assert len(
            owners
        ) <= 1, 'There must only be one owner, got %s instead' % owners
        if len(owners) == 1:
            return owners[0]

    __owner__ = property(get_owner, set_owner)

    @classmethod
    def class_implemented_interfaces(cls):
        return get_direct_interfaces(cls)

    def implemented_interfaces(self):
        return self.class_implemented_interfaces() + list(
            directlyProvidedBy(self).interfaces())

    @classmethod
    def get_class_features(cls):
        return set([i.__name__ for i in cls.class_implemented_interfaces()])

    def get_features(self):
        return set([i.__name__ for i in self.implemented_interfaces()])

    def set_features(self, values):
        """
        Features is a pseudo attribute which allows us to treat marker interfaces as if they were
        attributes. This special setter behaves like the tags setter, allowing addition and removal
        of individual marker interfaces from omsh.

        """
        # we have to reset the object otherwise indexing framework
        # won't update removed values
        features = set(self.get_features())

        def marker_by_name(name):
            for i in getattr(self, '__markers__', []):
                if i.__name__ == name:
                    return i
            return None

        if not any(i.startswith('-') or i.startswith('+') for i in values):
            for i in getattr(self, '__markers__', []):
                noLongerProvides(self, i)

        # ignore empty strings
        for value in (i for i in values if i):
            op = value[0] if value[0] in ['-', '+'] else None
            if op:
                value = value[1:]

            marker = marker_by_name(value)
            if marker:
                if op == '-':
                    if value in features:
                        noLongerProvides(self, marker)
                else:
                    alsoProvides(self, marker)

    features = property(get_features, set_features)

    def __setattr__(self, name, value):
        super(Model, self).__setattr__(name, value)
        if not name.startswith('_') and name not in self._mtime_blacklist:
            # useful debug info, but very verbose
            #logger.debug('setattr: %s: %s' % (self, name))
            self._mtime = time.time()