def suffix(obj): if IContainer.providedBy(follow_symlinks(obj)): return '/' elif ICommand.providedBy(follow_symlinks(obj)): return '*' elif isinstance(obj, Symlink): return '@' else: return ''
def set_acl(self, obj, inherit, allow_perms, deny_perms, del_perms, recursive=False): prinrole = IPrincipalRoleManager(obj) auth = getUtility(IAuthentication, context=None) obj.inherit_permissions = inherit def mod_perm(what, setter, p): kind, principal, perms = p.split(':') if not perms: return prin = auth.getPrincipal(principal) if isinstance(prin, Group) and kind == 'u': self.write( "No such user '%s', it's a group, perhaps you mean 'g:%s:%s'\n" % (principal, principal, perms)) return elif type(prin) is User and kind == 'g': self.write( "No such group '%s', it's a user (%s), perhaps you mean 'u:%s:%s'\n" % (principal, prin, principal, perms)) return for perm in perms.strip(): if perm not in Role.nick_to_role: raise NoSuchPermission(perm) role = Role.nick_to_role[perm].id self.write("%s permission '%s', principal '%s'\n" % (what, role, principal)) setter(role, principal) def apply_perms(prinrole): for p in allow_perms or []: mod_perm("Allowing", prinrole.assignRoleToPrincipal, p) for p in deny_perms or []: mod_perm("Denying", prinrole.removeRoleFromPrincipal, p) for p in del_perms or []: mod_perm("Unsetting", prinrole.unsetRoleForPrincipal, p) apply_perms(prinrole) seen = [obj] if recursive and IContainer.providedBy(obj): for sobj in obj.listcontent(): if follow_symlinks(sobj) not in seen: prinrole = IPrincipalRoleManager(sobj) sobj.inherit_permissions = inherit seen.append(follow_symlinks(sobj)) apply_perms(prinrole)
def _do_print_acl(self, obj, verbose, recursive, seen): prinrole = IPrincipalRoleManager(obj) auth = getUtility(IAuthentication, context=None) user_allow = collections.defaultdict(list) user_deny = collections.defaultdict(list) users = set() for role, principal, setting in prinrole.getPrincipalsAndRoles(): users.add(principal) if setting.getName() == 'Allow': user_allow[principal].append(role) else: user_deny[principal].append(role) for principal in users: def formatted_perms(perms): prin = auth.getPrincipal(principal) typ = 'group' if isinstance(prin, Group) else 'user' if verbose: def grants(i): return ','.join( '@%s' % i[0] for i in rolePermissionManager.getPermissionsForRole(i) if i[0] != 'oms.nothing') return (typ, principal, ''.join( '%s{%s}' % (Role.role_to_nick.get(i, '(%s)' % i), grants(i)) for i in sorted(perms))) else: return (typ, principal, ''.join( Role.role_to_nick.get(i, '(%s)' % i) for i in sorted(perms))) if principal in user_allow: self.write("%s:%s:+%s\n" % formatted_perms(user_allow[principal])) if principal in user_deny: self.write("%s:%s:-%s\n" % formatted_perms(user_deny[principal])) if recursive and IContainer.providedBy(follow_symlinks(obj)): for sobj in follow_symlinks(obj).listcontent(): if follow_symlinks(sobj) not in seen: seen.append(sobj) self.write('%s:\n' % canonical_path(sobj)) self._do_print_acl(sobj, verbose, recursive, seen)
def mv_and_inherit(): machines = db.get_root()['oms_root']['machines'] computes = db.get_root()['oms_root']['computes'] try: destination_compute = machines[destination.__name__] vm_compute = follow_symlinks(computes[self.context.__name__]) vm_compute.failure = destination_compute.failure vm_compute.suspicious = destination_compute.suspicious dvms = follow_symlinks(destination_compute['vms']) dvms.add(vm_compute) log.msg('Model moved.', system='migrate') except IndexError: log.msg('Model NOT moved: destination compute or vms do not exist', system='migrate') except KeyError: log.msg('Model NOT moved: already moved by sync?', system='migrate')
def make_long_lines(container): def get_symlink_nicknames(item): for method in (lambda item: [canonical_path(item)], lambda item: getattr(follow_symlinks(item), 'nicknames', [])): try: for n in method(item): yield n except Unauthorized: log.err(system='security') def nick(item): return (get_symlink_nicknames(item) if isinstance(item, Symlink) else getattr(item, 'nicknames', [])) def owner(item): return item.__owner__ or 'root' return [(('%s %s %s\t%s\t%s\n' % (pretty_effective_perms(self.protocol.interaction, follow_symlinks(subobj)), owner(subobj), datetime.datetime.fromtimestamp(subobj.mtime).isoformat() if not subobj.__transient__ else ' <transient> ', pretty_name(subobj), ' : '.join(nick(subobj)))).encode('utf-8')) for subobj in container]
def traverse_path(obj, path): """Starting from the given object, traverses all its descendant objects to find an object that matches the given path. Returns a tuple that contains the object up to which the traversal was successful plus all objects that led to that object, and the part of the path that could not be resolved. """ path = parse_path(path) if not path: return [obj], [] ret = [obj] while path: name = path[0] try: traverser = ITraverser(ret[-1]) except TypeError: break next_obj = follow_symlinks(traverser.traverse(name)) if not next_obj: break ret.append(next_obj) path = path[1:] return ret[1:], path
def make_long_lines(container): def get_symlink_nicknames(item): for method in (lambda item: [canonical_path(item)], lambda item: getattr(follow_symlinks(item), 'nicknames', [])): try: for n in method(item): yield n except Unauthorized: log.err(system='security') def nick(item): return (get_symlink_nicknames(item) if isinstance( item, Symlink) else getattr(item, 'nicknames', [])) def owner(item): return item.__owner__ or 'root' return [ (('%s %s %s\t%s\t%s\n' % (pretty_effective_perms(self.protocol.interaction, follow_symlinks(subobj)), owner(subobj), datetime.datetime.fromtimestamp( subobj.mtime).isoformat() if not subobj.__transient__ else ' <transient> ', pretty_name(subobj), ' : '.join(nick(subobj)))).encode('utf-8')) for subobj in container ]
def set_acl(self, obj, inherit, allow_perms, deny_perms, del_perms, recursive=False): prinrole = IPrincipalRoleManager(obj) auth = getUtility(IAuthentication, context=None) obj.inherit_permissions = inherit def mod_perm(what, setter, p): kind, principal, perms = p.split(':') if not perms: return prin = auth.getPrincipal(principal) if isinstance(prin, Group) and kind == 'u': self.write("No such user '%s', it's a group, perhaps you mean 'g:%s:%s'\n" % (principal, principal, perms)) return elif type(prin) is User and kind == 'g': self.write("No such group '%s', it's a user (%s), perhaps you mean 'u:%s:%s'\n" % (principal, prin, principal, perms)) return for perm in perms.strip(): if perm not in Role.nick_to_role: raise NoSuchPermission(perm) role = Role.nick_to_role[perm].id self.write("%s permission '%s', principal '%s'\n" % (what, role, principal)) setter(role, principal) def apply_perms(prinrole): for p in allow_perms or []: mod_perm("Allowing", prinrole.assignRoleToPrincipal, p) for p in deny_perms or []: mod_perm("Denying", prinrole.removeRoleFromPrincipal, p) for p in del_perms or []: mod_perm("Unsetting", prinrole.unsetRoleForPrincipal, p) apply_perms(prinrole) seen = [obj] if recursive and IContainer.providedBy(obj): for sobj in obj.listcontent(): if follow_symlinks(sobj) not in seen: prinrole = IPrincipalRoleManager(sobj) sobj.inherit_permissions = inherit seen.append(follow_symlinks(sobj)) apply_perms(prinrole)
def get_symlink_nicknames(item): for method in (lambda item: [canonical_path(item)], lambda item: getattr(follow_symlinks(item), 'nicknames', [])): try: for n in method(item): yield n except Unauthorized: log.err(system='security')
def get_vms_if_not_empty(): vms = follow_symlinks(self.context['vms']) or [] for vm in vms: if IVirtualCompute.providedBy(vm): return vms log.msg('%s: no VMs' % (self.context.hostname), system='metrics', logLevel=logging.DEBUG)
def canonical_path(item): path = [] from opennode.oms.security.authentication import sudo while item: p = sudo(follow_symlinks(sudo(item))) assert p.__name__ is not None, '%s.__name__ is None' % p path.insert(0, p.__name__) item = p.__parent__ return '/'.join(path)
def mv_and_inherit(): machines = db.get_root()['oms_root']['machines'] computes = db.get_root()['oms_root']['computes'] try: destination_compute = machines[destination.__name__] vm_compute = follow_symlinks( computes[self.context.__name__]) vm_compute.failure = destination_compute.failure vm_compute.suspicious = destination_compute.suspicious dvms = follow_symlinks(destination_compute['vms']) dvms.add(vm_compute) log.msg('Model moved.', system='migrate') except IndexError: log.msg( 'Model NOT moved: destination compute or vms do not exist', system='migrate') except KeyError: log.msg('Model NOT moved: already moved by sync?', system='migrate')
def _do_print_acl(self, obj, verbose, recursive, seen): prinrole = IPrincipalRoleManager(obj) auth = getUtility(IAuthentication, context=None) user_allow = collections.defaultdict(list) user_deny = collections.defaultdict(list) users = set() for role, principal, setting in prinrole.getPrincipalsAndRoles(): users.add(principal) if setting.getName() == 'Allow': user_allow[principal].append(role) else: user_deny[principal].append(role) for principal in users: def formatted_perms(perms): prin = auth.getPrincipal(principal) typ = 'group' if isinstance(prin, Group) else 'user' if verbose: def grants(i): return ','.join('@%s' % i[0] for i in rolePermissionManager.getPermissionsForRole(i) if i[0] != 'oms.nothing') return (typ, principal, ''.join('%s{%s}' % (Role.role_to_nick.get(i, '(%s)' % i), grants(i)) for i in sorted(perms))) else: return (typ, principal, ''.join(Role.role_to_nick.get(i, '(%s)' % i) for i in sorted(perms))) if principal in user_allow: self.write("%s:%s:+%s\n" % formatted_perms(user_allow[principal])) if principal in user_deny: self.write("%s:%s:-%s\n" % formatted_perms(user_deny[principal])) if recursive and IContainer.providedBy(follow_symlinks(obj)): for sobj in follow_symlinks(obj).listcontent(): if follow_symlinks(sobj) not in seen: seen.append(sobj) self.write('%s:\n' % canonical_path(sobj)) self._do_print_acl(sobj, verbose, recursive, seen)
def get_compute_ips(): try: computes = map(follow_symlinks, filter(lambda c: ICompute.providedBy(follow_symlinks(c)), db.get_root()['oms_root']['computes'].listcontent())) pools = db.get_root()['oms_root']['ippools'] for c in computes: ip = IPAddress(c.ipv4_address.split('/')[0]) pool = pools.find_pool(ip) if pool is not None and not pool.get(ip): log.msg('Marking %s as used...' % ip, system='sync-ippool') pool.use(ip) except Exception: log.err(system='sync-ippool') raise
def get_compute_ips(): try: computes = map( follow_symlinks, filter( lambda c: ICompute.providedBy(follow_symlinks(c)), db.get_root()['oms_root']['computes'].listcontent())) pools = db.get_root()['oms_root']['ippools'] for c in computes: ip = IPAddress(c.ipv4_address.split('/')[0]) pool = pools.find_pool(ip) if pool is not None and not pool.get(ip): log.msg('Marking %s as used...' % ip, system='sync-ippool') pool.use(ip) except Exception: log.err(system='sync-ippool') raise
def update_templates(container, templates): if not container['templates']: container.add(Templates()) template_container = container['templates'] for template in templates: name = template['template_name'] if not template_container['by-name'][name]: template_container.add( Template(unicode(name), get_u(template, 'domain_type'))) t = template_container['by-name'][name].target t.cores = (get_i(template, 'vcpu_min'), get_i(template, 'vcpu'), max(-1, get_i(template, 'vcpu_max'))) t.memory = (get_f(template, 'memory_min'), get_f(template, 'memory'), max(-1.0, get_f(template, 'memory_max'))) t.swap = (get_f(template, 'swap_min'), get_f(template, 'swap'), max(-1.0, get_f(template, 'swap_max'))) t.disk = (get_f(template, 'disk_min'), get_f(template, 'disk'), max(-1.0, get_f(template, 'disk_max'))) t.nameserver = get_u(template, 'nameserver') t.username = get_u(template, 'username') t.password = get_u(template, 'passwd') t.cpu_limit = (get_i(template, 'vcpulimit_min'), get_i(template, 'vcpulimit')) t.ip = get_u(template, 'ip_address') # delete templates no more offered upstream template_names = template_container['by-name'].listnames() vanished_template_names = set(template_names).difference( template['template_name'] for template in templates) for template in vanished_template_names: template_container.remove( follow_symlinks(template_container['by-name'][template]))
def update_templates(container, templates): if not container['templates']: container.add(Templates()) template_container = container['templates'] for template in templates: name = template['template_name'] if not template_container['by-name'][name]: template_container.add(Template(unicode(name), get_u(template, 'domain_type'))) t = template_container['by-name'][name].target t.cores = (get_i(template, 'vcpu_min'), get_i(template, 'vcpu'), max(-1, get_i(template, 'vcpu_max'))) t.memory = (get_f(template, 'memory_min'), get_f(template, 'memory'), max(-1.0, get_f(template, 'memory_max'))) t.swap = (get_f(template, 'swap_min'), get_f(template, 'swap'), max(-1.0, get_f(template, 'swap_max'))) t.disk = (get_f(template, 'disk_min'), get_f(template, 'disk'), max(-1.0, get_f(template, 'disk_max'))) t.nameserver = get_u(template, 'nameserver') t.username = get_u(template, 'username') t.password = get_u(template, 'passwd') t.cpu_limit = (get_i(template, 'vcpulimit_min'), get_i(template, 'vcpulimit')) t.ip = get_u(template, 'ip_address') # delete templates no more offered upstream template_names = template_container['by-name'].listnames() vanished_template_names = set(template_names).difference( template['template_name'] for template in templates) for template in vanished_template_names: template_container.remove(follow_symlinks(template_container['by-name'][template]))
def _execute(self, cmd, args): @db.ro_transact def get_destination(): return (args.__parent__ if IVirtualizationContainer.providedBy(args) else cmd.traverse(args.dest_path)) @db.ro_transact def get_hostname(target): return target.hostname name = yield db.get(self.context, '__name__') source_vms = yield db.get(self.context, '__parent__') destination = yield get_destination() assert ICompute.providedBy( destination), 'Destination must be a Compute' assert not IVirtualCompute.providedBy( destination), 'Cannot migrate to a VM' destination_hostname = yield get_hostname(destination) destination_vms = follow_symlinks(destination['vms']) assert (yield db.get(destination_vms, 'backend')) == (yield db.get(source_vms, 'backend')),\ 'Destination backend is different from source' @db.transact def set_additional_keys(): self._additional_keys = [ canonical_path(destination_vms), canonical_path(destination) ] yield set_additional_keys() yield self.reacquire_until_clear() log.msg('Initiating migration for %s to %s' % (name, destination_hostname), system='migrate') try: if not (yield self._check_vm_pre(cmd, name, destination_hostname, destination_vms)): return source_submitter = IVirtualizationContainerSubmitter(source_vms) yield source_submitter.submit(IMigrateVM, name, destination_hostname, (not args.offline), False) log.msg('Migration done. Checking... %s' % destination_vms, system='migrate') if (yield self._check_vm_post(cmd, name, destination_hostname, destination_vms)): log.msg('Migration finished successfully!', system='migrate') @db.transact def mv_and_inherit(): machines = db.get_root()['oms_root']['machines'] computes = db.get_root()['oms_root']['computes'] try: destination_compute = machines[destination.__name__] vm_compute = follow_symlinks( computes[self.context.__name__]) vm_compute.failure = destination_compute.failure vm_compute.suspicious = destination_compute.suspicious dvms = follow_symlinks(destination_compute['vms']) dvms.add(vm_compute) log.msg('Model moved.', system='migrate') except IndexError: log.msg( 'Model NOT moved: destination compute or vms do not exist', system='migrate') except KeyError: log.msg('Model NOT moved: already moved by sync?', system='migrate') yield mv_and_inherit() except OperationRemoteError as e: self._action_log(cmd, 'Failed migration of %s to %s: remote error %s' % (name, destination_hostname, '\n%s' % e.remote_tb if e.remote_tb else ''), logLevel=ERROR, system='migrate')
def get_current_ctid(): ctidlist = db.get_root()['oms_root']['computes']['openvz'] return max([follow_symlinks(symlink).ctid for symlink in ctidlist.listcontent()] + [100])
def check(): machines = db.get_root()['oms_root']['machines'] machine = follow_symlinks(machines['by-name'][host]) if not mgt_stack.providedBy(machine): return return machine
def _execute(self, cmd, args): @db.ro_transact def get_destination(): return (args.__parent__ if IVirtualizationContainer.providedBy(args) else cmd.traverse(args.dest_path)) @db.ro_transact def get_hostname(target): return target.hostname name = yield db.get(self.context, '__name__') source_vms = yield db.get(self.context, '__parent__') destination = yield get_destination() assert ICompute.providedBy(destination), 'Destination must be a Compute' assert not IVirtualCompute.providedBy(destination), 'Cannot migrate to a VM' destination_hostname = yield get_hostname(destination) destination_vms = follow_symlinks(destination['vms']) assert (yield db.get(destination_vms, 'backend')) == (yield db.get(source_vms, 'backend')),\ 'Destination backend is different from source' @db.transact def set_additional_keys(): self._additional_keys = [canonical_path(destination_vms), canonical_path(destination)] yield set_additional_keys() yield self.reacquire_until_clear() log.msg('Initiating migration for %s to %s' % (name, destination_hostname), system='migrate') try: if not (yield self._check_vm_pre(name, destination_hostname, destination_vms)): return source_submitter = IVirtualizationContainerSubmitter(source_vms) yield source_submitter.submit(IMigrateVM, name, destination_hostname, (not args.offline), False) log.msg('Migration done. Checking... %s' % destination_vms, system='migrate') if (yield self._check_vm_post(cmd, name, destination_hostname, destination_vms)): log.msg('Migration finished successfully!', system='migrate') @db.transact def mv_and_inherit(): machines = db.get_root()['oms_root']['machines'] computes = db.get_root()['oms_root']['computes'] try: destination_compute = machines[destination.__name__] vm_compute = follow_symlinks(computes[self.context.__name__]) vm_compute.failure = destination_compute.failure vm_compute.suspicious = destination_compute.suspicious dvms = follow_symlinks(destination_compute['vms']) dvms.add(vm_compute) log.msg('Model moved.', system='migrate') except IndexError: log.msg('Model NOT moved: destination compute or vms do not exist', system='migrate') except KeyError: log.msg('Model NOT moved: already moved by sync?', system='migrate') yield mv_and_inherit() except OperationRemoteError as e: self._action_log(cmd, 'Failed migration of %s to %s: remote error %s' % ( name, destination_hostname, '\n%s' % e.remote_tb if e.remote_tb else ''), logLevel=ERROR, system='migrate')
def subject(self, *args, **kwargs): return tuple((follow_symlinks(args[0]), ))
def set_additional_keys(): vms = follow_symlinks(self.context['vms']) if vms: self._additional_keys = (canonical_path(vms),)
def _sync_vms_transact(self, remote_vms): local_vms = [i for i in self.context.listcontent() if IVirtualCompute.providedBy(i)] remote_uuids = set(i['uuid'] for i in remote_vms) local_uuids = set(i.__name__ for i in local_vms) root = db.get_root()['oms_root'] machines = root['machines'] for vm_uuid in remote_uuids.difference(local_uuids): remote_vm = [rvm for rvm in remote_vms if rvm['uuid'] == vm_uuid][0] existing_machine = follow_symlinks(machines['by-name'][remote_vm['name']]) if existing_machine: # XXX: this VM is a nested VM, for now let's hack it this way new_compute = Symlink(existing_machine.__name__, existing_machine) self.context._add(new_compute) else: log.msg('Adding virtual compute %s...' % vm_uuid, system='v12n-sync', logLevel=logging.WARNING) new_compute = Compute(unicode(remote_vm['name']), unicode(remote_vm['state'])) new_compute.__name__ = vm_uuid new_compute.template = unicode(remote_vm['template']) alsoProvides(new_compute, IVirtualCompute) alsoProvides(new_compute, IDeployed) # for now let's force new synced computes to not have salt installed # XXX: not sure if removing a parent interface will remove the child also noLongerProvides(new_compute, IManageable) self.context.add(new_compute) for vm_uuid in remote_uuids.intersection(local_uuids): noLongerProvides(self.context[vm_uuid], IUndeployed) alsoProvides(self.context[vm_uuid], IDeployed) for vm_uuid in local_uuids.difference(remote_uuids): if IDeploying.providedBy(self.context[vm_uuid]): log.msg("Don't delete undeployed VM while in IDeploying state", system='v12n') continue noLongerProvides(self.context[vm_uuid], IDeployed) alsoProvides(self.context[vm_uuid], IUndeployed) self.context[vm_uuid].state = u'inactive' if get_config().getboolean('sync', 'delete_on_sync'): log.msg("Deleting compute %s" % vm_uuid, system='v12n-sync', logLevel=logging.WARNING) compute = self.context[vm_uuid] del self.context[vm_uuid] handle(compute, ModelDeletedEvent(self.context)) # TODO: eliminate cross-import between compute and v12ncontainer from opennode.knot.backend.compute import ICompute from opennode.knot.backend.syncaction import SyncAction # sync each vm for compute in self.context.listcontent(): if not IVirtualCompute.providedBy(compute): continue log.msg('Attempting to sync %s' % compute, system='sync-vms') if not ICompute.providedBy(compute.__parent__.__parent__): log.msg('Inconsistent data: %s, Compute is expected. Attempting to fix %s' % (compute.__parent__.__parent__, compute), system='sync-vms', logLevel=logging.WARNING) compute.__parent__ = self.context log.msg('Fixing %s %s' % (compute, 'successful!' if ICompute.providedBy(compute.__parent__.__parent__) else 'failed!'), system='sync-vms', logLevel=logging.WARNING) if not ICompute.providedBy(compute.__parent__.__parent__): return action = SyncAction(compute) matching = [rvm for rvm in remote_vms if rvm['uuid'] == compute.__name__] if not matching: continue remote_vm = matching[0] # todo delegate all this into the action itself default_console = action._default_console() action._sync_consoles() action.sync_owner_transact(remote_vm) action.sync_vm(remote_vm) action.create_default_console(default_console)
def set_additional_keys(): vms = follow_symlinks(self.context['vms']) if vms: self._additional_keys = (canonical_path(vms), )
def subject(self, *args, **kwargs): return tuple((follow_symlinks(args[0]),))
def get_current_ctid(): ctidlist = db.get_root()['oms_root']['computes']['openvz'] return max( [follow_symlinks(symlink).ctid for symlink in ctidlist.listcontent()] + [100])