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 find_share(dbobj, resourcegroup, share, ignore=None, error=NotFoundException): """ Find a suitable share resource. dbobj is either a host, cluster, or metacluster. If dbobj is a cluster that is part of a metacluster, and the share is not defined at the cluster level, then it is also searched for at the metacluster level. If resourcegroup is not None, the share must be part of the named resourcegroup; otherwise, it must not be inside a resourcegroup. If the value of ignore is an existing Share instance, then that instance will be ignored by find_share. """ session = object_session(dbobj) if resourcegroup: dbrg = ResourceGroup.get_unique(session, name=resourcegroup, holder=dbobj.resholder) if dbrg: holder = dbrg.resholder else: holder = None else: holder = dbobj.resholder if holder: q = session.query(Share) q = q.filter_by(name=share, holder=holder) if ignore: q = q.filter_by(id != ignore.id) # The (name, holder) pair is unique, so we cannot get multiple results # here try: return q.one() except NoResultFound: pass # No luck. If this was a cluster, try to find the share at the metacluster # level, but if even that fails, report the problem for the cluster. if hasattr(dbobj, 'metacluster') and dbobj.metacluster: try: return find_share(dbobj.metacluster, resourcegroup, share, ignore=ignore, error=error) except error: pass if resourcegroup: msg = "{0} does not have share {1!s} assigned to it in " + \ "resourcegroup {2}.".format(dbobj, share, resourcegroup) else: msg = "{0} does not have share {1!s} assigned to it.".format(dbobj, share) raise error(msg)
def render(self, session, logger, resourcegroup, required_type, hostname, cluster, **arguments): validate_nlist_key("resourcegroup", resourcegroup) if required_type is not None: Resource.polymorphic_subclass(required_type, "Unknown resource type") if required_type == "resourcegroup": raise ArgumentError("A resourcegroup can't hold other " "resourcegroups.") holder = get_resource_holder(session, hostname, cluster, compel=False) ResourceGroup.get_unique(session, name=resourcegroup, holder=holder, preclude=True) dbrg = ResourceGroup(name=resourcegroup, required_type=required_type) return add_resource(session, logger, holder, dbrg)
def render(self, session, logger, resourcegroup, required_type, hostname, cluster, **arguments): validate_basic("resourcegroup", resourcegroup) if required_type is not None: Resource.polymorphic_subclass(required_type, "Unknown resource type") if required_type == "resourcegroup": raise ArgumentError("A resourcegroup can't hold other " "resourcegroups.") holder = get_resource_holder(session, hostname, cluster, compel=False) ResourceGroup.get_unique(session, name=resourcegroup, holder=holder, preclude=True) dbrg = ResourceGroup(name=resourcegroup, required_type=required_type) return add_resource(session, logger, holder, dbrg)
def render(self, session, logger, resourcegroup, hostname, cluster, **arguments): holder = get_resource_holder(session, hostname, cluster, compel=True) dbrg = ResourceGroup.get_unique(session, name=resourcegroup, holder=holder, compel=True) # Deleting service addresses can't be done with just cascading if dbrg.resholder: for res in dbrg.resholder.resources: if isinstance(res, ServiceAddress): raise ArgumentError("{0} contains {1:l}, please delete " "it first.".format(dbrg, res)) del_resource(session, logger, dbrg) return
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_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 find_share(dbobj, resourcegroup, share, ignore=None, error=NotFoundException): """ Find a suitable share resource. dbobj is either a host, cluster, or metacluster. If dbobj is a cluster that is part of a metacluster, and the share is not defined at the cluster level, then it is also searched for at the metacluster level. If resourcegroup is not None, the share must be part of the named resourcegroup; otherwise, it must not be inside a resourcegroup. If the value of ignore is an existing Share instance, then that instance will be ignored by find_share. """ session = object_session(dbobj) if resourcegroup: dbrg = ResourceGroup.get_unique(session, name=resourcegroup, holder=dbobj.resholder) if dbrg: holder = dbrg.resholder else: holder = None else: holder = dbobj.resholder if holder: q = session.query(Share) q = q.filter_by(name=share, holder=holder) if ignore: q = q.filter_by(id != ignore.id) # The (name, holder) pair is unique, so we cannot get multiple results # here try: return q.one() except NoResultFound: pass # No luck. If this was a cluster, try to find the share at the metacluster # level, but if even that fails, report the problem for the cluster. if hasattr(dbobj, 'metacluster') and dbobj.metacluster: try: return find_share(dbobj.metacluster, resourcegroup, share, ignore=ignore, error=error) except error: pass if resourcegroup: msg = "{0} does not have share {1!s} assigned to it in " + \ "resourcegroup {2}.".format(dbobj, share, resourcegroup) else: msg = "{0} does not have share {1!s} assigned to it.".format( dbobj, share) raise error(msg)