diff options
Diffstat (limited to 'cloudinit/config/cc_rh_subscription.py')
-rw-r--r-- | cloudinit/config/cc_rh_subscription.py | 408 |
1 files changed, 0 insertions, 408 deletions
diff --git a/cloudinit/config/cc_rh_subscription.py b/cloudinit/config/cc_rh_subscription.py deleted file mode 100644 index 3a113aea..00000000 --- a/cloudinit/config/cc_rh_subscription.py +++ /dev/null @@ -1,408 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2015 Red Hat, Inc. -# -# Author: Brent Baude <bbaude@redhat.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 3, as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -from cloudinit import util - - -def handle(name, cfg, _cloud, log, _args): - sm = SubscriptionManager(cfg) - sm.log = log - if not sm.is_configured(): - log.debug("%s: module not configured.", name) - return None - - if not sm.is_registered(): - try: - verify, verify_msg = sm._verify_keys() - if verify is not True: - raise SubscriptionError(verify_msg) - cont = sm.rhn_register() - if not cont: - raise SubscriptionError("Registration failed or did not " - "run completely") - - # Splitting up the registration, auto-attach, and servicelevel - # commands because the error codes, messages from subman are not - # specific enough. - - # Attempt to change the service level - if sm.auto_attach and sm.servicelevel is not None: - if not sm._set_service_level(): - raise SubscriptionError("Setting of service-level " - "failed") - else: - sm.log.debug("Completed auto-attach with service level") - elif sm.auto_attach: - if not sm._set_auto_attach(): - raise SubscriptionError("Setting auto-attach failed") - else: - sm.log.debug("Completed auto-attach") - - if sm.pools is not None: - if not isinstance(sm.pools, list): - pool_fail = "Pools must in the format of a list" - raise SubscriptionError(pool_fail) - - return_stat = sm.addPool(sm.pools) - if not return_stat: - raise SubscriptionError("Unable to attach pools {0}" - .format(sm.pools)) - if (sm.enable_repo is not None) or (sm.disable_repo is not None): - return_stat = sm.update_repos(sm.enable_repo, sm.disable_repo) - if not return_stat: - raise SubscriptionError("Unable to add or remove repos") - sm.log_success("rh_subscription plugin completed successfully") - except SubscriptionError as e: - sm.log_warn(str(e)) - sm.log_warn("rh_subscription plugin did not complete successfully") - else: - sm.log_success("System is already registered") - - -class SubscriptionError(Exception): - pass - - -class SubscriptionManager(object): - valid_rh_keys = ['org', 'activation-key', 'username', 'password', - 'disable-repo', 'enable-repo', 'add-pool', - 'rhsm-baseurl', 'server-hostname', - 'auto-attach', 'service-level'] - - def __init__(self, cfg): - self.cfg = cfg - self.rhel_cfg = self.cfg.get('rh_subscription', {}) - self.rhsm_baseurl = self.rhel_cfg.get('rhsm-baseurl') - self.server_hostname = self.rhel_cfg.get('server-hostname') - self.pools = self.rhel_cfg.get('add-pool') - self.activation_key = self.rhel_cfg.get('activation-key') - self.org = self.rhel_cfg.get('org') - self.userid = self.rhel_cfg.get('username') - self.password = self.rhel_cfg.get('password') - self.auto_attach = self.rhel_cfg.get('auto-attach') - self.enable_repo = self.rhel_cfg.get('enable-repo') - self.disable_repo = self.rhel_cfg.get('disable-repo') - self.servicelevel = self.rhel_cfg.get('service-level') - self.subman = ['subscription-manager'] - - def log_success(self, msg): - '''Simple wrapper for logging info messages. Useful for unittests''' - self.log.info(msg) - - def log_warn(self, msg): - '''Simple wrapper for logging warning messages. Useful for unittests''' - self.log.warn(msg) - - def _verify_keys(self): - ''' - Checks that the keys in the rh_subscription dict from the user-data - are what we expect. - ''' - - for k in self.rhel_cfg: - if k not in self.valid_rh_keys: - bad_key = "{0} is not a valid key for rh_subscription. "\ - "Valid keys are: "\ - "{1}".format(k, ', '.join(self.valid_rh_keys)) - return False, bad_key - - # Check for bad auto-attach value - if (self.auto_attach is not None) and \ - not (util.is_true(self.auto_attach) or - util.is_false(self.auto_attach)): - not_bool = "The key auto-attach must be a boolean value "\ - "(True/False " - return False, not_bool - - if (self.servicelevel is not None) and ((not self.auto_attach) or - (util.is_false(str(self.auto_attach)))): - no_auto = ("The service-level key must be used in conjunction " - "with the auto-attach key. Please re-run with " - "auto-attach: True") - return False, no_auto - return True, None - - def is_registered(self): - ''' - Checks if the system is already registered and returns - True if so, else False - ''' - cmd = ['identity'] - - try: - self._sub_man_cli(cmd) - except util.ProcessExecutionError: - return False - - return True - - def _sub_man_cli(self, cmd, logstring_val=False): - ''' - Uses the prefered cloud-init subprocess def of util.subp - and runs subscription-manager. Breaking this to a - separate function for later use in mocking and unittests - ''' - cmd = self.subman + cmd - return util.subp(cmd, logstring=logstring_val) - - def rhn_register(self): - ''' - Registers the system by userid and password or activation key - and org. Returns True when successful False when not. - ''' - - if (self.activation_key is not None) and (self.org is not None): - # register by activation key - cmd = ['register', '--activationkey={0}'. - format(self.activation_key), '--org={0}'.format(self.org)] - - # If the baseurl and/or server url are passed in, we register - # with them. - - if self.rhsm_baseurl is not None: - cmd.append("--baseurl={0}".format(self.rhsm_baseurl)) - - if self.server_hostname is not None: - cmd.append("--serverurl={0}".format(self.server_hostname)) - - try: - return_out, return_err = self._sub_man_cli(cmd, - logstring_val=True) - except util.ProcessExecutionError as e: - if e.stdout == "": - self.log_warn("Registration failed due " - "to: {0}".format(e.stderr)) - return False - - elif (self.userid is not None) and (self.password is not None): - # register by username and password - cmd = ['register', '--username={0}'.format(self.userid), - '--password={0}'.format(self.password)] - - # If the baseurl and/or server url are passed in, we register - # with them. - - if self.rhsm_baseurl is not None: - cmd.append("--baseurl={0}".format(self.rhsm_baseurl)) - - if self.server_hostname is not None: - cmd.append("--serverurl={0}".format(self.server_hostname)) - - # Attempting to register the system only - try: - return_out, return_err = self._sub_man_cli(cmd, - logstring_val=True) - except util.ProcessExecutionError as e: - if e.stdout == "": - self.log_warn("Registration failed due " - "to: {0}".format(e.stderr)) - return False - - else: - self.log_warn("Unable to register system due to incomplete " - "information.") - self.log_warn("Use either activationkey and org *or* userid " - "and password") - return False - - reg_id = return_out.split("ID: ")[1].rstrip() - self.log.debug("Registered successfully with ID {0}".format(reg_id)) - return True - - def _set_service_level(self): - cmd = ['attach', '--auto', '--servicelevel={0}' - .format(self.servicelevel)] - - try: - return_out, return_err = self._sub_man_cli(cmd) - except util.ProcessExecutionError as e: - if e.stdout.rstrip() != '': - for line in e.stdout.split("\n"): - if line is not '': - self.log_warn(line) - else: - self.log_warn("Setting the service level failed with: " - "{0}".format(e.stderr.strip())) - return False - for line in return_out.split("\n"): - if line is not "": - self.log.debug(line) - return True - - def _set_auto_attach(self): - cmd = ['attach', '--auto'] - try: - return_out, return_err = self._sub_man_cli(cmd) - except util.ProcessExecutionError: - self.log_warn("Auto-attach failed with: " - "{0}]".format(return_err.strip())) - return False - for line in return_out.split("\n"): - if line is not "": - self.log.debug(line) - return True - - def _getPools(self): - ''' - Gets the list pools for the active subscription and returns them - in list form. - ''' - available = [] - consumed = [] - - # Get all available pools - cmd = ['list', '--available', '--pool-only'] - results, errors = self._sub_man_cli(cmd) - available = (results.rstrip()).split("\n") - - # Get all consumed pools - cmd = ['list', '--consumed', '--pool-only'] - results, errors = self._sub_man_cli(cmd) - consumed = (results.rstrip()).split("\n") - - return available, consumed - - def _getRepos(self): - ''' - Obtains the current list of active yum repositories and returns - them in list form. - ''' - - cmd = ['repos', '--list-enabled'] - return_out, return_err = self._sub_man_cli(cmd) - active_repos = [] - for repo in return_out.split("\n"): - if "Repo ID:" in repo: - active_repos.append((repo.split(':')[1]).strip()) - - cmd = ['repos', '--list-disabled'] - return_out, return_err = self._sub_man_cli(cmd) - - inactive_repos = [] - for repo in return_out.split("\n"): - if "Repo ID:" in repo: - inactive_repos.append((repo.split(':')[1]).strip()) - return active_repos, inactive_repos - - def addPool(self, pools): - ''' - Takes a list of subscription pools and "attaches" them to the - current subscription - ''' - - # An empty list was passed - if len(pools) == 0: - self.log.debug("No pools to attach") - return True - - pool_available, pool_consumed = self._getPools() - pool_list = [] - cmd = ['attach'] - for pool in pools: - if (pool not in pool_consumed) and (pool in pool_available): - pool_list.append('--pool={0}'.format(pool)) - else: - self.log_warn("Pool {0} is not available".format(pool)) - if len(pool_list) > 0: - cmd.extend(pool_list) - try: - self._sub_man_cli(cmd) - self.log.debug("Attached the following pools to your " - "system: %s" % (", ".join(pool_list)) - .replace('--pool=', '')) - return True - except util.ProcessExecutionError as e: - self.log_warn("Unable to attach pool {0} " - "due to {1}".format(pool, e)) - return False - - def update_repos(self, erepos, drepos): - ''' - Takes a list of yum repo ids that need to be disabled or enabled; then - it verifies if they are already enabled or disabled and finally - executes the action to disable or enable - ''' - - if (erepos is not None) and (not isinstance(erepos, list)): - self.log_warn("Repo IDs must in the format of a list.") - return False - - if (drepos is not None) and (not isinstance(drepos, list)): - self.log_warn("Repo IDs must in the format of a list.") - return False - - # Bail if both lists are not populated - if (len(erepos) == 0) and (len(drepos) == 0): - self.log.debug("No repo IDs to enable or disable") - return True - - active_repos, inactive_repos = self._getRepos() - # Creating a list of repoids to be enabled - enable_list = [] - enable_list_fail = [] - for repoid in erepos: - if (repoid in inactive_repos): - enable_list.append("--enable={0}".format(repoid)) - else: - enable_list_fail.append(repoid) - - # Creating a list of repoids to be disabled - disable_list = [] - disable_list_fail = [] - for repoid in drepos: - if repoid in active_repos: - disable_list.append("--disable={0}".format(repoid)) - else: - disable_list_fail.append(repoid) - - # Logging any repos that are already enabled or disabled - if len(enable_list_fail) > 0: - for fail in enable_list_fail: - # Check if the repo exists or not - if fail in active_repos: - self.log.debug("Repo {0} is already enabled".format(fail)) - else: - self.log_warn("Repo {0} does not appear to " - "exist".format(fail)) - if len(disable_list_fail) > 0: - for fail in disable_list_fail: - self.log.debug("Repo {0} not disabled " - "because it is not enabled".format(fail)) - - cmd = ['repos'] - if len(enable_list) > 0: - cmd.extend(enable_list) - if len(disable_list) > 0: - cmd.extend(disable_list) - - try: - self._sub_man_cli(cmd) - except util.ProcessExecutionError as e: - self.log_warn("Unable to alter repos due to {0}".format(e)) - return False - - if len(enable_list) > 0: - self.log.debug("Enabled the following repos: %s" % - (", ".join(enable_list)).replace('--enable=', '')) - if len(disable_list) > 0: - self.log.debug("Disabled the following repos: %s" % - (", ".join(disable_list)).replace('--disable=', '')) - return True - - def is_configured(self): - return bool((self.userid and self.password) or self.activation_key) |