def get_unique_instance(type): # We'll use numeric identifiers for instances id = 1 while str(id) in RoleSettings.get_instances(type): id += 1 log.debug1("Generating unique instance %s" % str(id)) return str(id)
def installPackages(self): """install packages""" log.debug1("%s.installPackages()", self._log_prefix) # are there any groups or packages to install? if len(self._settings["packages"]) < 1: log.debug1("No groups or packages to install") yield None return # There is a bug in DNF where it will return exit code 1 if # all of the packages requested are @group and their contents # already installed. There's a hacky workaround by adding a # non-@group package to the command-line, so we'll add rolekit dnf_install = [ "dnf", "-y", "install", "rolekit" ] + \ self._settings["packages"] result = yield async.subprocess_future(dnf_install) if result.status: # If the subprocess returned non-zero, raise an exception raise RolekitError(COMMAND_FAILED, "%d" % result.status) # Completed successfully yield None
def __decommission_async(self, force, sender): # Make sure we are in the proper state self.assert_state(READY_TO_START, ERROR) # Log log.debug1("%s.decommission(%s)", self._log_prefix, force) # Change state to decommissioning self.change_state(DECOMMISSIONING) # Call do_decommission try: yield async.call_future(self.do_decommission_async(force=force, sender=sender)) except Exception as e: self.change_state(ERROR, error=str(e), write=True) if not force: raise # Uninstall firewall self.uninstallFirewall() # Remove extension unit files self.cleanup_targets() # Remove the instance self.__remove_instance()
def PropertiesChanged(self, interface_name, changed_properties, invalidated_properties): interface_name = dbus_to_python(interface_name) changed_properties = dbus_to_python(changed_properties) invalidated_properties = dbus_to_python(invalidated_properties) log.debug1("PropertiesChanged('%s', '%s', '%s')", interface_name, changed_properties, invalidated_properties)
def Set(self, interface_name, property_name, new_value, sender=None): interface_name = dbus_to_python(interface_name) property_name = dbus_to_python(property_name) new_value = dbus_to_python(new_value) log.debug1("%s.Set('%s', '%s', '%s')", self._log_prefix, interface_name, property_name, new_value) if interface_name != DBUS_INTERFACE_ROLE: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.UnknownInterface: " "RolekitD does not implement %s" % interface_name) if property_name in self._exported_rw_properties: if not hasattr(self, "__check_%s", property_name): raise RolekitError(MISSING_CHECK, property_name) x = getattr(self, "__check_%s", property_name) x(new_value) self._settings.set(property_name, new_value) self._settings.write() self.PropertiesChanged(interface_name, { property_name: new_value }, [ ]) elif property_name in self._exported_ro_properties: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.PropertyReadOnly: " "Property '%s' is read-only" % property_name) else: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.AccessDenied: " "Property '%s' does not exist" % property_name)
def Introspect(self, sender=None): log.debug1("%s.Introspect()" % self._log_prefix) data = super(DBusRole, self).Introspect(self.path, self.busname.get_bus()) return dbus_introspection_add_properties(self, data, DBUS_INTERFACE_ROLE)
def main(): args = parse_cmdline() setup_logging(args) log.debug1("Arguments: %s" % sys.argv) # Read the password from stdin user_pass = input(False) # Check for valid database and user names # We restrict this to having only letters, numbers # and underscores, for safety against SQL injection identifier = re.compile(r"^[^\d\W]\w*\Z") if not identifier.match(args.user): log.error("The user name was not a valid identifier.") sys.exit(1) # Connect to the local database via 'peer' conn = psycopg2.connect(database=args.database) conn.autocommit = True log.info1("Connected to local database '%s'" % args.database) cur = conn.cursor() # Construct the SQL statement sql_msg = ("ALTER ROLE %s WITH ENCRYPTED PASSWORD" % (args.user) + " %(pwd)s;") log.info1("Executing: %s" % sql_msg) log.debug10("Password: [%s]", user_pass) # Submit the request cur.execute(sql_msg, {'pwd': user_pass}) sys.exit(0)
def _signal_receiver(self, *args, **kwargs): _args = [] for arg in args: _args.append(dbus_to_python(arg)) args = _args if not "member" in kwargs: return signal = kwargs["member"] interface = kwargs["interface"] if interface != DBUS_INTERFACE or signal != "NotifyUnitFailed" or len(args) != 2: return log.debug1("NotifyUnitFailed('%s', '%s')", args[0], args[1]) for obj in self._roles: if obj.get_name() != args[0]: continue instances = obj.get_instances() for instance_name in instances: if instance_name != args[1]: continue instance = instances[instance_name] if instance._settings["state"] == RUNNING: state = target_unit_state(instance.target_unit) if state != "active": instance.change_state(ERROR, write=True)
def getAllRoleInstances(self, sender=None): """ return the list of all role instances """ log.debug1("getAllRoleInstances()") ret_list = [] for obj in self._roles: for instance in obj.get_instances().values(): ret_list.append(instance) return ret_list
def getNamedRole(self, name, sender=None): """ return the role with the name, otherwise raise error """ name = dbus_to_python(name) log.debug1("getNamedRole('%s')", name) for obj in self._roles: if obj.get_name() == name: return obj raise RolekitError(INVALID_ROLE, name)
def getNamedInstance(self, name, sender=None): """ return the role with the name, otherwise raise error """ name = dbus_to_python(name) log.debug1("%s.getNamedInstance('%s')", self._log_prefix, name) instance_escaped_name = dbus_label_escape(name) if instance_escaped_name in self._instances: return self._instances[instance_escaped_name] raise RolekitError(INVALID_INSTANCE, name)
def __redeploy_async(self, values, sender): values = dbus_to_python(values) # Make sure we are in the proper state self.assert_state(READY_TO_START, ERROR) # Log log.debug1("%s.redeploy(%s)", self._log_prefix, values) # Check values try: self.check_values(values) except Exception as e: # checking of values failed, set state to error self.change_state(ERROR, error=str(e), write=True) raise try: # Change to redeploying state self.change_state(REDEPLOYING) # Uninstall firewall self.uninstallFirewall() # Copy _DEFAULTS to self._settings self.copy_defaults() # Install package groups and packages log.debug9("TRACE: Installing packages") yield async.call_future(self.installPackages()) # Install firewall self.installFirewall() # Call do_redeploy_async log.debug9("TRACE: Performing role-specific redeployment") yield async.call_future(self.do_redeploy_async(values, sender)) # Continue only after successful deployment: # Apply values to self._settings log.debug9("TRACE: role-specific redeployment complete, applying values") self.apply_values(values) # Change to ready to start state self.change_state(READY_TO_START, write=True) # Attempt to start the newly-deployed role # We do this because many role-installers will conclude by # starting anyway and we want to ensure that our role mechanism # is in sync with them. log.debug9("TRACE: Starting %s" % self.get_name()) yield async.call_future(self.__start_async(sender)) except Exception as e: # Something failed, set state to error self.change_state(ERROR, error=str(e), write=True) raise
def __job_removed_handler(self, job_id, job_path, unit, result): """SYSTEMD_MANAGER_INTERFACE.JobRemoved signal handler""" log.debug1("systemd JobRemoved signal: %s" % repr((job_id, job_path, unit, result))) if job_path in self.__pending_jobs: self.__job_results[unit] = result self.__pending_jobs.remove(job_path) if len(self.__pending_jobs) == 0: self.__future.set_result(self.__job_results)
def _check_property(self, prop, value): try: super(Role, self)._check_property(prop, value) except RolekitError as e: if e.code == MISSING_CHECK: log.debug1("Unvalidated property: %s" % prop) else: log.debug1("Property %s did not validate" % prop) raise
def start(self): """ starts rolekit """ log.debug1("start()") try: os.makedirs(ETC_ROLEKIT_ROLES) except OSError as e: if e.errno == errno.EEXIST: if not os.path.isdir(ETC_ROLEKIT_ROLES): log.fatal("'%s' is not a directory.", e.strerror) else: log.fatal("Failed to create '%s': %s", e.strerror) raise else: log.info1("Created missing '%s'.", ETC_ROLEKIT_ROLES) path = ROLEKIT_ROLES if not os.path.exists(path) or not os.path.isdir(path): log.error("Role directory '%s' does not exist.", path) return for name in sorted(os.listdir(path)): directory = "%s/%s" % (path, name) if not os.path.isdir(directory): continue if not os.path.exists(os.path.join(directory, "role.py")): continue log.debug1("Loading role '%s'", name) escaped_name = dbus_label_escape(name) try: if os.path.exists(os.path.join(directory, "role.py")): mod = imp.load_source(name, "%s/role.py" % directory) # get Role from module role = getattr(mod, "Role") # create role object that contains the role instance class obj = DBusRole(role, name, directory, self.busname, "%s/%s" % (DBUS_PATH_ROLES, escaped_name), persistent=self.persistent) if obj in self._roles: log.error("Duplicate role '%s'", obj.get_name()) else: self._roles.append(obj) except RolekitError as msg: log.error("Failed to load role '%s': %s", name, msg) continue except Exception as msg: log.error("Failed to load role '%s':", name) log.exception() continue
def GetAll(self, interface_name, sender=None): interface_name = dbus_to_python(interface_name) log.debug1("GetAll('%s')", interface_name) if interface_name != DBUS_INTERFACE: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.UnknownInterface: " "roled does not implement %s" % interface_name ) return {"version": self._get_property("version"), "roles": self._get_property("roles")}
def getAllRoleInstancesByState(self, state, sender=None): """ return the list of all roles instances that are in a particular state """ state = dbus_to_python(state) log.debug1("getAllRoleInstancesByState('%s')", state) ret_list = [] for obj in self._roles: for instance in obj.get_instances().values(): if instance.get_state() == state: ret_list.append(instance) return ret_list
def resetError(self, sender=None): """resets error state in a role""" # Make sure we are in the proper state self.assert_state(ERROR) # Log log.debug1("%s.resetError()", self._log_prefix) # Change to state updating self.change_state(READY_TO_START, write=True)
def __stop_async(self, sender): self.assert_state(RUNNING) log.debug1("%s.stop()", self._log_prefix) try: self.change_state(STOPPING) yield async.call_future(self.do_stop_async(sender)) self.change_state(READY_TO_START, write=True) except: self.change_state(ERROR, write=True) raise
def Get(self, interface_name, property_name, sender=None): # get a property interface_name = dbus_to_python(interface_name) property_name = dbus_to_python(property_name) log.debug1("Get('%s', '%s')", interface_name, property_name) if interface_name != DBUS_INTERFACE: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.UnknownInterface: " "roled does not implement %s" % interface_name ) return self._get_property(property_name)
def __deploy_async(self, name, values): values = dbus_to_python(values) name = dbus_to_python(name) log.debug1("role.%s.deploy('%s', %s)", self._escaped_name, name, values) # limit role instances to max instances per role if len(self._instances) >= self._role._MAX_INSTANCES: raise RolekitError(TOO_MANY_INSTANCES, "> %d" % self._role._MAX_INSTANCES) # TODO: lock # create name if empty if not name: id = 1 while str(id) in self._instances: id += 1 name = str(id) # create escaped name and check if it is already in use instance_escaped_name = dbus_label_escape(name) if instance_escaped_name in self._instances: raise RolekitError(NAME_CONFLICT, instance_escaped_name) settings = RoleSettings(self._name, name) try: settings.read() except ValueError as e: raise RolekitError(NAME_CONFLICT, settings.filename) except IOError as e: pass else: raise RolekitError(NAME_CONFLICT, settings.filename) # create role role = self._role( self, name, self._name, self._directory, settings, self._path, "%s/%s/%s" % (DBUS_PATH_ROLES, self._escaped_name, instance_escaped_name), persistent=self.persistent, ) self._instances[instance_escaped_name] = role self.InstanceAdded(instance_escaped_name) # TODO: unlock # deploy role, lock in role now result = yield async.call_future(role.deploy_async(values)) yield result
def GetAll(self, interface_name, sender=None): interface_name = dbus_to_python(interface_name) log.debug1("%s.GetAll('%s')", self._log_prefix, interface_name) if interface_name != DBUS_INTERFACE_ROLE: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.UnknownInterface: " "RolekitD does not implement %s" % interface_name) ret = dbus.Dictionary(signature = "sv") for x in [ "name", "DEFAULTS" ]: ret[x] = self.get_dbus_property(x) return ret
def Get(self, interface_name, property_name, sender=None): # get a property interface_name = dbus_to_python(interface_name) property_name = dbus_to_python(property_name) log.debug1("%s.Get('%s', '%s')", self._log_prefix, interface_name, property_name) if interface_name != DBUS_INTERFACE_ROLE_INSTANCE: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.UnknownInterface: " "RolekitD does not implement %s" % interface_name) return self.get_dbus_property(self, property_name)
def target_unit_state(target_unit): with SystemdJobHandler() as job_handler: job_path = job_handler.manager.GetUnit(target_unit) bus = slip.dbus.SystemBus() obj = bus.get_object(SYSTEMD_MANAGER_NAME, job_path) props = dbus.Interface( obj, dbus_interface='org.freedesktop.DBus.Properties') systemd_state = dbus_to_python(props.Get(SYSTEMD_UNIT_INTERFACE, "ActiveState")) rolekit_state = map_systemd_state(systemd_state); log.debug1("Detected systemd state %s" % rolekit_state) return rolekit_state raise RolekitError(COMMAND_FAILED, "Could not get role state.")
def __redeploy_async(self, values, sender): values = dbus_to_python(values) # Make sure we are in the proper state self.assert_state(READY_TO_START, ERROR) # Log log.debug1("%s.redeploy(%s)", self._log_prefix, values) # Check values try: self.check_values(values) except: # checking of values failed, set state to error self.change_state(ERROR, write=True) raise try: # Change to redeploying state self.change_state(REDEPLOYING) # Copy _DEFAULTS to self._settings self.copy_defaults() # Call do_redeploy_async yield async.call_future(self.do_redeploy_async(values, sender)) # Continue only after successful deployment: # Apply values to self._settings try: self.apply_values(values) except: # applying of values failed, set state to error self.change_state(ERROR, write=True) raise # Change to ready to start state self.change_state(READY_TO_START, write=True) # Attempt to start the newly-deployed role # We do this because many role-installers will conclude by # starting anyway and we want to ensure that our role mechanism # is in sync with them. yield async.call_future(self.__start_async(sender)) except: # Something failed, set state to error self.change_state(ERROR, write=True) raise
def __init__(self, role, name, directory, *args, **kwargs): """The DBUS_INTERFACE_ROLE implementation :param role: RoleBase descendant :param name: Role name :param directory: FIXME: unused??? :param path: (Implicit in *args) FIXME: unused??? """ super(DBusRole, self).__init__(*args, **kwargs) self._path = args[0] self._role = role self._name = name self._escaped_name = dbus_label_escape(name) self._directory = directory self._instances = {} # create instances for stored instance settings path = "%s/%s" % (ETC_ROLEKIT_ROLES, self._name) if os.path.exists(path) and os.path.isdir(path): for name in sorted(os.listdir(path)): if not name.endswith(".json"): continue instance = name[:-5] log.debug1("Loading '%s' instance '%s'", self._name, instance) settings = RoleSettings(self._name, instance) try: settings.read() except ValueError as e: log.error("Failed to load '%s' instance '%s': %s", self._name, instance, e) continue instance_escaped_name = dbus_label_escape(instance) if instance_escaped_name in self._instances: raise RolekitError(NAME_CONFLICT, instance_escaped_name) role = self._role( self, instance, self._name, self._directory, settings, self._path, "%s/%s/%s" % (DBUS_PATH_ROLES, self._escaped_name, instance_escaped_name), persistent=self.persistent, ) self._instances[instance_escaped_name] = role self.timeout_restart()
def restart(self, reply_handler, error_handler, sender=None): """restart role""" # Make sure we are in the proper state self.assert_state(RUNNING) # Log log.debug1("%s.restart()", self._log_prefix) # Stop self.stop(reply_handler, error_handler, sender) # Start if state is ready to start self.assert_state(READY_TO_START) self.start(reply_handler, error_handler, sender)
def stop_services_async(self): """stop_services_async""" log.debug1("%s.stop_services_async()", self._log_prefix) with SystemdJobHandler() as job_handler: target_unit = "role-%s-%s.target" % (self._type, self.get_name()) job_path = job_handler.manager.StopUnit(target_unit, "replace") job_handler.register_job(job_path) job_results = yield job_handler.all_jobs_done_future() if any([x for x in job_results.values() if x not in ("skipped", "done")]): details = ", ".join(["%s: %s" % item for item in job_results.items()]) raise RolekitError(COMMAND_FAILED, "Stopping services failed: %s" % details)
def Set(self, interface_name, property_name, new_value, sender=None): interface_name = dbus_to_python(interface_name) property_name = dbus_to_python(property_name) new_value = dbus_to_python(new_value) log.debug1("Set('%s', '%s', '%s')", interface_name, property_name, new_value) self.accessCheck(sender) if interface_name != DBUS_INTERFACE: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.UnknownInterface: " "roled does not implement %s" % interface_name ) raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.AccessDenied: " "Property '%s' is not settable" % property_name )
def GetAll(self, interface_name, sender=None): interface_name = dbus_to_python(interface_name) log.debug1("config.GetAll('%s')", interface_name) if interface_name != DBUS_INTERFACE_ROLE_INSTANCE: raise dbus.exceptions.DBusException( "org.freedesktop.DBus.Error.UnknownInterface: " "RolekitD does not implement %s" % interface_name) ret = { } for name in self._DEFAULTS: ret[name] = self.get_dbus_property(self, name) # lasterror is not in _DEFAULTS, but in _settings ret["lasterror"] = self.get_dbus_property(self, "lasterror") return ret
def Introspect(self, sender=None): log.debug1("Introspect()") data = super(RoleD, self).Introspect(self.path, self.busname.get_bus()) return dbus_introspection_add_properties(self, data, DBUS_INTERFACE)
def InstanceRemoved(self, name): log.debug1("%s.InstanceRemoved('%s')", self._log_prefix, name)
def __init__(self, role, name, directory, *args, **kwargs): """The DBUS_INTERFACE_ROLE implementation :param role: RoleBase descendant :param name: Role name :param directory: FIXME: unused??? :param path: (Implicit in *args) FIXME: unused??? """ super(DBusRole, self).__init__(*args, **kwargs) self.busname = args[0] self.path = args[1] self._role = role self._name = name self._escaped_name = dbus_label_escape(name) self._log_prefix = "role.%s" % self._escaped_name self._directory = directory self._instances = {} # create instances for stored instance settings path = "%s/%s" % (ETC_ROLEKIT_ROLES, self.get_name()) if os.path.exists(path) and os.path.isdir(path): for name in sorted(os.listdir(path)): if not name.endswith(".json"): continue instance = name[:-5] log.debug1("Loading '%s' instance '%s'", self.get_name(), instance) settings = RoleSettings(self.get_name(), instance) try: settings.read() except ValueError as e: log.error("Failed to load '%s' instance '%s': %s", self.get_name(), instance, e) continue instance_escaped_name = dbus_label_escape(instance) if instance_escaped_name in self._instances: raise RolekitError(NAME_CONFLICT, instance_escaped_name) role = self._role(self, instance, self.get_name(), self._directory, settings, self.busname, "%s/%s/%s" % (DBUS_PATH_ROLES, self._escaped_name, instance_escaped_name), persistent=self.persistent) # During roled startup (the only time this function should be # called), if any role is in a transitional state, it can only # mean that roled was terminated while it was still supposed # to be doing something. # Always set the state to ERROR here if it's in a transitional state, # otherwise we won't be able to clean it up. if role._settings["state"] in TRANSITIONAL_STATES: role.change_state(state=ERROR, write=True, error="roled terminated unexpectedly") self._instances[instance_escaped_name] = role self.timeout_restart()
def restartServices(self): """restart services""" log.debug1("%s.restartServices()", self._log_prefix) raise NotImplementedError()
def deploy_async(self, values, sender=None): """deploy role""" remove_instance = False values = dbus_to_python(values) # Make sure we are in the proper state self.assert_state(NASCENT) # Log log.debug1("%s.deploy(%s)", self._log_prefix, values) # Check values try: self.check_values(values) except Exception as e: # Check values failed, remove the instance again if verification # failed, set state to error, save it (will be visible in the # .old backup file). self.change_state(ERROR, error=str(e), write=True) # cleanup self.__remove_instance() raise try: # Change to deploying state self.change_state(DEPLOYING) # Copy _DEFAULTS to self._settings self.copy_defaults() # Install package groups and packages log.debug9("TRACE: Installing packages") yield async .call_future(self.installPackages()) # Install firewall self.installFirewall() # Call do_deploy log.debug9("TRACE: Performing role-specific deployment") try: target = yield async .call_future( self.do_deploy_async(values, sender)) except RolekitError as e: if e.code == INVALID_VALUE: # If we failed because the input values were incorrect, # also remove the instance. remove_instance = True raise # Continue only after successful deployment: # Apply values to self._settings log.debug9( "TRACE: role-specific deployment complete, applying values") self.apply_values(values) # Set up systemd target files log.debug9("TRACE: Creating systemd target files") self.create_target(target) # Change to ready to start state self.change_state(READY_TO_START, write=True) # In case this was a nextboot deployment, make sure to remove # the deferred role settings and systemd unit try: # Remove settings deferredsettings = "%s/%s/%s.json" % ( ETC_ROLEKIT_DEFERREDROLES, self.get_type(), self.get_name()) os.unlink(deferredsettings) # Remove systemd service unit deferredunit = "%s/deferred-role-deployment-%s-%s.service" % ( SYSTEMD_UNITS, self.get_type(), self.get_name()) disable_units([deferredunit]) os.unlink(deferredunit) except FileNotFoundError: # Files didn't exist; ignore that pass except PermissionError: # SELinux bug? log.fatal( "ERROR: permission error attempting to delete %s or %s" % (deferredsettings, deferredunit)) # We'll continue anyway, since the service should be runnable at this point # The ConditionPathExists will prevent the service from trying to deploy # again # Tell systemd to reload the daemon configuration log.debug9("Reloading systemd units\n") with SystemdJobHandler() as job_handler: job_handler.manager.Reload() # Start monitoring the role self.monitor_unit() # Attempt to start the newly-deployed role # We do this because many role-installers will conclude by # starting anyway and we want to ensure that our role mechanism # is in sync with them. log.debug9("TRACE: Starting %s" % self.get_name()) yield async .call_future(self.__start_async(sender)) except Exception as e: # Something failed, set state to error self.change_state(ERROR, error=str(e), write=True) if remove_instance: self.__remove_instance() raise
def updateFirewall(self): """update firewall""" log.debug1("%s.updateFirewall()", self._log_prefix) self.uninstallFirewall() self.installFirewall()
def deploy_async(self, values, sender=None): """deploy role""" remove_instance = False values = dbus_to_python(values) # Make sure we are in the proper state self.assert_state(NASCENT) # Log log.debug1("%s.deploy(%s)", self._log_prefix, values) # Check values try: self.check_values(values) except: # Check values failed, remove the instance again if verification # failed, set state to error, save it (will be visible in the # .old backup file). self.change_state(ERROR, write=True) # cleanup self.__remove_instance() raise try: # Change to deploying state self.change_state(DEPLOYING) # Copy _DEFAULTS to self._settings self.copy_defaults() # Install package groups and packages log.debug9("TRACE: Installing packages") yield async.call_future(self.installPackages()) # Install firewall self.installFirewall() # Call do_deploy log.debug9("TRACE: Performing role-specific deployment") try: target = yield async.call_future(self.do_deploy_async(values, sender)) except RolekitError as e: if e.code == INVALID_VALUE: # If we failed because the input values were incorrect, # also remove the instance. remove_instance = True raise # Continue only after successful deployment: # Apply values to self._settings log.debug9("TRACE: role-specific deployment complete, applying values") self.apply_values(values) # Set up systemd target files log.debug9("TRACE: Creating systemd target files") self.create_target(target) # Change to ready to start state self.change_state(READY_TO_START, write=True) # Attempt to start the newly-deployed role # We do this because many role-installers will conclude by # starting anyway and we want to ensure that our role mechanism # is in sync with them. log.debug9("TRACE: Starting %s" % self.name) yield async.call_future(self.__start_async(sender)) except: # Something failed, set state to error self.change_state(ERROR, write=True) if remove_instance: self.__remove_instance() raise
def uninstallFirewall(self): """uninstall firewall""" log.debug1("%s.uninstallFirewall()", self._log_prefix) # Removes the settings that have been added in the installFirewall call # get applied changes from installFirewall call if "firewall-changes" in self._settings: fw_changes = self._settings["firewall-changes"] else: # fallback if there was a severe error in deploy before or while # installing the firewall fw_changes = { } # only continue if there are any changes if len(fw_changes) < 1: return # create firewall client fw = FirewallClient() # for all zones for zone in fw_changes: z_perm = fw.config().getZoneByName(zone).getSettings() if "services" in fw_changes[zone]: services = fw_changes[zone]["services"] for service in services: if "runtime" in services[service]: try: fw.removeService(zone, service) except Exception as e: if not "NOT_ENABLED" in str(e): raise if "permanent" in services[service]: try: z_perm.removeService(service) except Exception as e: if not "NOT_ENABLED" in str(e): raise if "ports" in fw_changes[zone]: ports = fw_changes[zone]["ports"] for port_proto in ports: port, proto = port_proto.split("/") if "runtime" in ports[port_proto]: try: fw.removePort(zone, port, proto) except Exception as e: if not "NOT_ENABLED" in str(e): raise if "permanent" in ports[port_proto]: try: z_perm.removePort(port, proto) except Exception as e: if not "NOT_ENABLED" in str(e): raise fw.config().getZoneByName(zone).update(z_perm) # clear fw_changes and save it in _settings fw_changes.clear() self._settings["firewall-changes"] = fw_changes self._settings.write()
def StateChanged(self, state): log.debug1("%s.StateChanged('%s')", self._log_prefix, state)
def installFirewall(self): """install firewall""" log.debug1("%s.installFirewall()", self._log_prefix) # are there any firewall settings to apply? if len(self._settings["firewall"]["services"]) + \ len(self._settings["firewall"]["ports"]) < 1: return # create firewall client fw = FirewallClient() log.debug2("TRACE: Firewall client created") # Make sure firewalld is running by getting the # default zone try: default_zone = fw.getDefaultZone() except DBusException: # firewalld is not running log.error("Firewalld is not running or rolekit cannot access it") raise # save changes to the firewall try: fw_changes = self._settings["firewall-changes"] except KeyError: fw_changes = { } log.debug2("TRACE: Checking for zones: {}".format(self._settings)) try: zones = self._settings["firewall_zones"] except KeyError: zones = [] # if firewall_zones setting is empty, use default zone if len(zones) < 1: zones = [ default_zone ] log.debug2("TRACE: default zone {}".format(zones[0])) for zone in zones: log.debug2("TRACE: Processing zone {0}".format(zone)) # get permanent zone settings, run-time settings do not need a # special treatment z_perm = fw.config().getZoneByName(zone).getSettings() for service in self._settings["firewall"]["services"]: try: fw.addService(zone, service, 0) except Exception as e: if not "ALREADY_ENABLED" in str(e): raise else: fw_changes.setdefault(zone, {}).setdefault("services", {}).setdefault(service, []).append("runtime") if not z_perm.queryService(service): z_perm.addService(service) fw_changes.setdefault(zone, {}).setdefault("services", {}).setdefault(service, []).append("permanent") for port_proto in self._settings["firewall"]["ports"]: port, proto = port_proto.split("/") try: fw.addPort(zone, port, proto, 0) except Exception as e: if not "ALREADY_ENABLED" in str(e): raise else: fw_changes.setdefault(zone, {}).setdefault("ports", {}).setdefault(port_proto, []).append("runtime") if not z_perm.queryPort(port, proto): z_perm.addPort(port, proto) fw_changes.setdefault(zone, {}).setdefault("ports", {}).setdefault(port_proto, []).append("permanent") fw.config().getZoneByName(zone).update(z_perm) self._settings["firewall-changes"] = fw_changes self._settings.write()
def stop(self): """ stops rolekit """ log.debug1("stop()")
def PropertiesChanged(self, interface_name, changed_properties, invalidated_properties): log.debug1("config.PropertiesChanged('%s', '%s', '%s')", interface_name, changed_properties, invalidated_properties)
def getInstances(self, sender=None): """get role instances""" log.debug1("%s.getInstances()", self._log_prefix) return self._instances.values()