def del_path(self, path, compel=True): """ delete parameter specified at a path """ if not self.value: if compel: raise NotFoundException("No parameter of path=%s defined." % path) return pparts = Parameter.path_parts(path) try: ## delete the specified path self.__del_path(path) ## after deleting the leaf check if the parent node is empty ## if so delete it while pparts.pop(): if not pparts: break newpath = Parameter.topath(pparts) if self.get_path(newpath): break self.__del_path(newpath) ## coerce mutation of parameter since sqlalchemy ## cannot recognize parameter change self.value.changed() # pylint: disable=E1101 except: if compel: raise NotFoundException("No parameter of path=%s defined." % path)
def render(self, session, grn, eon_id, all, **arguments): q = session.query(Grn) if grn: q = q.filter_by(grn=grn) if eon_id: q = q.filter_by(eon_id=eon_id) result = q.all() if not result: if grn: raise NotFoundException("GRN %s not found." % grn) elif eon_id: raise NotFoundException("EON ID %s not found." % eon_id) return result
def hostname_to_host(session, hostname): # When the user asked for a host, returning "machine not found" does not # feel to be the right error message, even if it is technically correct. # It's a little tricky though: we don't want to suppress "dns domain not # found" parse_fqdn(session, hostname) try: dbmachine = Machine.get_unique(session, hostname, compel=True) except NotFoundException: raise NotFoundException("Host %s not found." % hostname) if not dbmachine.host: raise NotFoundException("{0} does not have a host " "assigned.".format(dbmachine)) return dbmachine.host
def render(self, generate, session, logger, personality, archetype, pre_feature, post_feature, param_tmpl, **kwargs): dbpersonality = Personality.get_unique(session, archetype=archetype, name=personality, compel=True) plenary = PlenaryPersonalityBase(dbpersonality, logger=logger) if pre_feature: plenary = PlenaryPersonalityPreFeature(dbpersonality, logger=logger) if post_feature: plenary = PlenaryPersonalityPostFeature(dbpersonality, logger=logger) if param_tmpl: param_templates = get_parameters_by_tmpl(dbpersonality) if param_tmpl in param_templates.keys(): plenary = PlenaryPersonalityParameter( dbpersonality, param_tmpl, param_templates[param_tmpl], logger=logger) else: raise NotFoundException("No parameter template %s%s found." % (param_tmpl, TEMPLATE_EXTENSION)) lines = [] if generate: lines.append(plenary._generate_content()) else: lines.append(plenary.read()) return lines
def render(self, session, ip, fqdn, all, network_environment, **arguments): dbnet_env = NetworkEnvironment.get_unique_or_default( session, network_environment) q = session.query(RouterAddress) q = q.join(Network) q = q.filter_by(network_environment=dbnet_env) q = q.options(contains_eager('network')) q = q.reset_joinpoint() q = q.options(undefer(RouterAddress.comments)) q = q.options(joinedload('location')) q = q.options(joinedload('dns_records')) if all: return q.all() if fqdn: dbdns_rec = ARecord.get_unique(session, fqdn=fqdn, compel=True) ip = dbdns_rec.ip errmsg = "named %s" % fqdn elif ip: errmsg = "with IP address %s" % ip else: raise ArgumentError("Please specify either --ip or --fqdn.") q = q.filter(RouterAddress.ip == ip) try: return q.one() except NoResultFound: raise NotFoundException("Router %s not found." % errmsg)
def render(self, session, gateway, ip, netmask, prefixlen, network_environment, **arguments): dbnet_env = NetworkEnvironment.get_unique_or_default( session, network_environment) dbnetwork = get_net_id_from_ip(session, gateway, dbnet_env) if netmask: dest = IPv4Network("%s/%s" % (ip, netmask)) else: dest = IPv4Network("%s/%s" % (ip, prefixlen)) q = session.query(StaticRoute) q = q.filter_by(network=dbnetwork) q = q.filter_by(gateway_ip=gateway) q = q.filter_by(dest_ip=dest.ip) q = q.filter_by(dest_cidr=dest.prefixlen) try: dbroute = q.one() except NoResultFound: raise NotFoundException("Static Route to {0} using gateway {1} " "not found.".format(dest, gateway)) session.delete(dbroute) session.flush() # TODO: refresh affected host templates return
def get_unique(cls, session, name, **kwargs): '''override the Base get_unique to deal with simple polymorphic table The API is simpler: only a single positional argument is supported. ''' if not isinstance(session, Session): # pragma: no cover raise TypeError("The first argument of get_unique() must be an " "SQLAlchemy session.") compel = kwargs.get('compel', False) preclude = kwargs.pop('preclude', False) clslabel = "state" if name not in cls.transitions: if not compel: return None msg = "%s %s not found." % (clslabel, name) raise NotFoundException(msg) query = session.query(cls).filter(getattr(cls, "name") == name) # We can't get NoResultFound since we've already checked the transition # table, and we can't get MultipleResultsFound since name is unique. obj = query.one() if preclude: msg = "%s %s already exists." % (clslabel, name) raise ArgumentError(msg) return obj
def render(self, session, principal, **arguments): try: options = [undefer("comments")] return get_or_create_user_principal(session, principal, False, False, options) except ArgumentError: raise NotFoundException("User principal %s not found." % principal)
def render(self, session, cluster, **arguments): q = session.query(Cluster) vm_q = session.query(VirtualMachine) vm_q = vm_q.join(ClusterResource, Cluster) if cluster: q = q.filter_by(name=cluster) vm_q = vm_q.filter_by(name=cluster) vm_q = vm_q.options(joinedload('machine'), joinedload('machine.primary_name'), joinedload('machine.primary_name.fqdn'), lazyload('machine.host')) q = q.options(subqueryload('_hosts'), joinedload('_hosts.host'), joinedload('_hosts.host.machine'), subqueryload('_metacluster'), joinedload('_metacluster.metacluster'), joinedload('resholder'), subqueryload('resholder.resources'), subqueryload('service_bindings'), subqueryload('allowed_personalities')) q = q.order_by(Cluster.name) dbclusters = q.all() if cluster and not dbclusters: raise NotFoundException("Cluster %s not found." % cluster) # Manual eager-loading of VM resources. All the code does is making sure # the data is pinned in the session's cache machines = {} for vm in vm_q: machines[vm.machine.machine_id] = vm return ClusterList(dbclusters)
def render(self, session, logger, machine, disk, controller, size, all, dbuser, **arguments): # Handle deprecated arguments if arguments.get("type", None): self.deprecated_option("type", "Please use --controller instead.", logger=logger, **arguments) controller = arguments["type"] if arguments.get("capacity", None): self.deprecated_option("capacity", "Please use --size instead.", logger=logger, **arguments) size = arguments["capacity"] dbmachine = Machine.get_unique(session, machine, compel=True) q = session.query(Disk).filter_by(machine=dbmachine) if disk: q = q.filter_by(device_name=disk) if controller: if controller not in controller_types: raise ArgumentError("%s is not a valid controller type, use " "one of: %s." % (controller, ", ".join(controller_types))) q = q.filter_by(controller_type=controller) if size is not None: q = q.filter_by(capacity=size) results = q.all() if len(results) == 0: raise NotFoundException("No disks found.") elif len(results) > 1 and not all: raise ArgumentError("More than one matching disks found. " "Use --all to delete them all.") for result in results: session.delete(result) session.flush() session.expire(dbmachine, ['disks']) plenary_machine = Plenary.get_plenary(dbmachine, logger=logger) key = plenary_machine.get_write_key() dbcontainer = dbmachine.vm_container if dbcontainer: plenary_container = Plenary.get_plenary(dbcontainer, logger=logger) key = CompileKey.merge([key, plenary_container.get_write_key()]) try: lock_queue.acquire(key) if dbcontainer: plenary_container.write(locked=True) plenary_machine.write(locked=True) except: plenary_machine.restore_stash() if dbcontainer: plenary_container.restore_stash() raise finally: lock_queue.release(key)
def render(self, session, dbuser, ip, fqdn, network_environment, **arguments): dbnet_env = NetworkEnvironment.get_unique_or_default(session, network_environment) self.az.check_network_environment(dbuser, dbnet_env) if fqdn: dbdns_rec = ARecord.get_unique(session, fqdn=fqdn, dns_environment=dbnet_env.dns_environment, compel=True) ip = dbdns_rec.ip elif not ip: raise ArgumentError("Please specify either --ip or --fqdn.") dbnetwork = get_net_id_from_ip(session, ip, dbnet_env) dbrouter = None for rtaddr in dbnetwork.routers: if rtaddr.ip == ip: dbrouter = rtaddr break if not dbrouter: raise NotFoundException("IP address {0} is not a router on " "{1:l}.".format(ip, dbnetwork)) map(delete_dns_record, dbrouter.dns_records) dbnetwork.routers.remove(dbrouter) session.flush() # TODO: update the templates of Zebra hosts on the network return
def get_net_id_from_ip(session, ip, network_environment=None): """Requires a session, and will return the Network for a given ip.""" if ip is None: return None if isinstance(network_environment, NetworkEnvironment): dbnet_env = network_environment else: dbnet_env = NetworkEnvironment.get_unique_or_default(session, network_environment) # Query the last network having an address smaller than the given ip. There # is no guarantee that the returned network does in fact contain the given # ip, so this must be checked separately. subq = session.query(Network.ip) subq = subq.filter_by(network_environment=dbnet_env) subq = subq.filter(Network.ip <= ip) subq = subq.order_by(desc(Network.ip)).limit(1) q = session.query(Network) q = q.filter_by(network_environment=dbnet_env) q = q.filter(Network.ip == subq.as_scalar()) net = q.first() if not net or not ip in net.network: raise NotFoundException("Could not determine network containing IP " "address %s." % ip) return net
def render(self, session, archetype, **arguments): dbarchetype = Archetype.get_unique(session, archetype, compel=True) if dbarchetype.paramdef_holder and \ dbarchetype.paramdef_holder.param_definitions: return dbarchetype.paramdef_holder.param_definitions raise NotFoundException("No parameter definitions found for " "archetype {0}.".format(archetype))
def get_user_principal(session, user): """Ignore the realm. This should probably be re-thought.""" dbusers = session.query(UserPrincipal).filter_by(name=user).all() if len(dbusers) > 1: raise InternalError("More than one user found for name %s" % user) if len(dbusers) == 0: raise NotFoundException("User '%s' not found." % user) return dbusers[0]
def lookup_grn(session, grn=None, eon_id=None, usable_only=True, logger=None, config=None, autoupdate=True): dbgrn = Grn.get_unique(session, grn=grn, eon_id=eon_id) if not dbgrn and autoupdate: if not config or not config.get("broker", "grn_to_eonid_map_location"): # pragma: no cover return None dbgrn = lookup_autoupdate(config, session, logger, grn, eon_id) if not dbgrn: if grn: raise NotFoundException("GRN %s not found." % grn) else: raise NotFoundException("EON ID %s not found." % eon_id) if usable_only and dbgrn.disabled: raise ArgumentError("GRN %s is not usable for new systems." % dbgrn.grn) return dbgrn
def render(self, session, feature, type, **arguments): dbfeature = Feature.get_unique(session, name=feature, feature_type=type, compel=True) if dbfeature.paramdef_holder and \ dbfeature.paramdef_holder.param_definitions: return dbfeature.paramdef_holder.param_definitions raise NotFoundException("No parameter definitions found for " "{0:l}.".format(dbfeature))
def get_resource_holder(session, hostname=None, cluster=None, resgroup=None, compel=True): who = None if hostname is not None: dbhost = hostname_to_host(session, hostname) who = dbhost.resholder if who is None: if compel: raise NotFoundException("{0} has no resources.".format(dbhost)) dbhost.resholder = HostResource(host=dbhost) session.add(dbhost.resholder) session.flush() who = dbhost.resholder if cluster is not None: dbcluster = Cluster.get_unique(session, cluster, compel=True) who = dbcluster.resholder if who is None: if compel: raise NotFoundException( "{0} has no resources.".format(dbcluster)) dbcluster.resholder = ClusterResource(cluster=dbcluster) session.add(dbcluster.resholder) session.flush() who = dbcluster.resholder if resgroup is not None: dbrg = ResourceGroup.get_unique(session, name=resgroup, holder=who, compel=True) who = dbrg.resholder if who is None: if compel: raise NotFoundException("{0} has no resources.".format(dbrg)) dbrg.resholder = BundleResource(resourcegroup=dbrg) session.add(dbrg.resholder) session.flush() who = dbrg.resholder return who
def get_service_instance(session, dbservice, instance): try: dbsi = session.query(ServiceInstance).filter_by( service=dbservice, name=instance).one() except NoResultFound: raise NotFoundException("Service %s, instance %s not found. Try `aq " "add service --service %s --instance %s` to " "add it." % (dbservice.name, instance, dbservice.name, instance)) return dbsi
def render(self, auditid, request, logger, **arguments): status = logger.get_status() if not status: raise NotFoundException("Audit ID %s not found." % auditid) arguments.pop("requestid") return CommandShowRequest.render(self, requestid=status.requestid, request=request, logger=logger, **arguments)
def render(self, requestid, request, logger, debug, **arguments): status = logger.get_status() if not status: raise NotFoundException("Request ID %s not found." % requestid) if debug: loglevel = DEBUG else: loglevel = CLIENT_INFO deferred = Deferred() status.add_subscriber(StatusWriter(deferred, request, loglevel)) return deferred
def get_network_byip(session, ipaddr, environment, query_options=None): try: q = session.query(Network) q = q.filter_by(network_environment=environment) q = q.filter_by(ip=ipaddr) if query_options: q = q.options(*query_options) dbnetwork = q.one() except NoResultFound: raise NotFoundException("Network with address %s not found." % ipaddr) return dbnetwork
def render(self, session, personality, archetype, **arguments): parameters = get_parameters(session, archetype=archetype, personality=personality) if parameters: return parameters raise NotFoundException("No parameters found for personality %s." % personality)
def render(self, session, logger, rack, type, clear, vlan, **arguments): dblocation = get_location(session, rack=rack) Switch.check_type(type) q = session.query(Switch) q = q.filter_by(location=dblocation) if type: q = q.filter_by(switch_type=type) switches = q.all() if not switches: raise NotFoundException("No switch found.") return self.poll(session, logger, switches, clear, vlan)
def __del_path(self, path): """ method to do the actual deletion """ pparts = Parameter.path_parts(path) lastnode = pparts.pop() dref = self.value try: for ppart in pparts: dref = dref[ppart] del dref[lastnode] except KeyError: raise NotFoundException("No parameter of path=%s defined." % path)
def render(self, session, service, archetype, personality, **arguments): dbpersonality = Personality.get_unique(session, name=personality, archetype=archetype, compel=True) dbservice = Service.get_unique(session, service, compel=True) try: dbservice.personalities.remove(dbpersonality) except ValueError: raise NotFoundException("Service %s required for archetype " "%s, personality %s not found." % (service, archetype, personality)) session.flush() return
def render(self, session, dns_domain, **kw): dbdns = DnsDomain.get_unique(session, dns_domain, compel=True) q = session.query(NsRecord).filter_by(dns_domain=dbdns) dba_record = ARecord.get_unique(session, fqdn=kw['fqdn'], compel=True) q = q.filter_by(a_record=dba_record) ns_rec = q.all() if not ns_rec: raise NotFoundException( "Could not find a dns_record for domain '%s'." % dns_domain) return ns_rec
def get_resource(session, holder, **arguments_in): # Filter out arguments that are not resources arguments = dict() mapper = inspect(Resource) for key, value in arguments_in.items(): if key in mapper.polymorphic_map and value is not None: arguments[mapper.polymorphic_map[key].class_] = value elif key == "reboot_intervention" and value is not None: # Sigh... Abbreviations are bad. arguments[RebootIntervention] = value # Resource groups are act both as resource and as holder. If there's another # resource type specified, then use it as a holder; if it is specified # alone, then use it as a resource. if ResourceGroup in arguments and len(arguments) > 1: rg_name = arguments.pop(ResourceGroup) if not holder.resholder: raise NotFoundException("{0} has no resources.".format(holder)) dbrg = ResourceGroup.get_unique(session, name=rg_name, holder=holder.resholder, compel=True) holder = dbrg if arguments: if len(arguments) > 1: raise ArgumentError("Only one resource type should be specified.") if not holder.resholder: raise NotFoundException("{0} has no resources.".format(holder)) cls, name = arguments.popitem() return cls.get_unique(session, name=name, holder=holder.resholder, compel=True) return None
def get_unique(cls, session, fqdn=None, name=None, dns_domain=None, dns_environment=None, compel=False, preclude=False, **kwargs): # Proxy FQDN lookup to the Fqdn class if not fqdn or not isinstance(fqdn, Fqdn): if not isinstance(dns_environment, DnsEnvironment): dns_environment = DnsEnvironment.get_unique_or_default( session, dns_environment) if fqdn: if name or dns_domain: # pragma: no cover raise TypeError("fqdn and name/dns_domain cannot be mixed") (name, dns_domain) = parse_fqdn(session, fqdn) try: # Do not pass preclude=True to Fqdn fqdn = Fqdn.get_unique(session, name=name, dns_domain=dns_domain, dns_environment=dns_environment, compel=compel) except NotFoundException: # Replace the "Fqdn ... not found" message with a more user # friendly one msg = "%s %s.%s, %s not found." % ( cls._get_class_label(), name, dns_domain, format(dns_environment, "l")) raise NotFoundException(msg) if not fqdn: return None # We already have the FQDN, no need to load it again if "query_options" not in kwargs: kwargs["query_options"] = [lazyload("fqdn")] result = super(DnsRecord, cls).get_unique(session, fqdn=fqdn, compel=compel, preclude=preclude, **kwargs) if result: # Make sure not to load the relation again if we already know its # value set_committed_value(result, 'fqdn', fqdn) return result
def get_network_byname(session, netname, environment, query_options=None): try: q = session.query(Network) q = q.filter_by(network_environment=environment) q = q.filter_by(name=netname) if query_options: q = q.options(*query_options) dbnetwork = q.one() except NoResultFound: raise NotFoundException("Network %s not found." % netname) # FIXME: network names should be unique except MultipleResultsFound: raise ArgumentError("There are multiple networks with name %s." % netname) return dbnetwork
def render(self, session, service, archetype, justification, user, **arguments): if not justification: raise AuthorizationException("Changing the required services of " "an archetype requires " "--justification.") validate_justification(user, justification) dbarchetype = Archetype.get_unique(session, archetype, compel=True) dbservice = Service.get_unique(session, service, compel=True) try: dbservice.archetypes.remove(dbarchetype) except ValueError: raise NotFoundException("Service %s required for archetype %s " "not found." % (service, archetype)) session.flush() return