def _validate_ssh_config(self): if not self.host: raise exceptions.AgentInstallerConfigurationError('Missing host') if not self.user: raise exceptions.AgentInstallerConfigurationError('Missing user') if not is_kerberos_env() and not self.password and not self.key: raise exceptions.AgentInstallerConfigurationError( 'Must specify either key or password')
def _set_install_method(self): install_method = cloudify_utils.internal.get_install_method( ctx.node.properties) # If the install method wasn't specified, it's remote by default self['install_method'] = install_method or 'remote' if self['install_method'] not in constants.AGENT_INSTALL_METHODS: raise exceptions.AgentInstallerConfigurationError( 'agent_config.install_method must be one of {0}' ' but found: {1}'.format(constants.AGENT_INSTALL_METHODS, self['install_method']))
def download(self, url, output_path=None, certificate_file=None, **attributes): """ Downloads the contents of the url. Following heuristic will be applied: 1. Try downloading with 'wget' command 2. if failed, try downloading with 'curl' command 3. if failed, raise a NonRecoverableError :param url: URL to the resource. :param output_path: Path where the resource will be downloaded to. If not specified, a temporary file will be used. :param certificate_file: a local cert file to use for SSL certificate verification. :param attributes: custom attributes passed directly to fabric's run command. :return: the output path. """ if output_path is None: output_path = self.mktemp() try: self.logger.debug('Attempting to locate wget on the host ' 'machine') self.run('which wget', **attributes) args = '-T 30 --header="{0}: {1}"'.format( CLOUDIFY_TOKEN_AUTHENTICATION_HEADER, ctx.rest_token) args += ' --ca-certificate {0}'.format(certificate_file) command = 'wget {0} {1} -O {2}'.format(args, url, output_path) except CommandExecutionException: try: self.logger.debug( 'wget not found. Attempting to locate cURL on the host ' 'machine') self.run('which curl', **attributes) args = '-H "{0}: {1}"'.format( CLOUDIFY_TOKEN_AUTHENTICATION_HEADER, ctx.rest_token) args += ' --cacert {0}'.format(certificate_file) command = 'curl {0} {1} -o {2}'.format(args, url, output_path) except CommandExecutionException: raise exceptions.AgentInstallerConfigurationError( 'Cannot find neither wget nor curl'.format(url)) self.run(command, **attributes) return output_path
def _load_private_key(self, key_contents): """Load the private key and return a paramiko PKey subclass. :param key_contents: the contents of a keyfile, as a string starting with "---BEGIN" :return: A paramiko PKey subclass - RSA, ECDSA or Ed25519 """ for cls in (RSAKey, ECDSAKey, Ed25519Key): try: return cls.from_private_key(StringIO(key_contents)) except SSHException: continue raise exceptions.AgentInstallerConfigurationError( 'Could not load the private key as an ' 'RSA, ECDSA, or Ed25519 key')
def _set_network(self): network = self.setdefault('network', constants.DEFAULT_NETWORK_NAME) networks = self.pop('networks', None) if networks: manager_ip = networks.get(network) if not manager_ip: raise exceptions.AgentInstallerConfigurationError( 'The network associated with the agent (`{0}`) does not ' 'appear in the list of manager networks assigned at ' 'bootstrap ({1})'.format(network, ', '.join(networks))) else: # Might be getting here when working in local workflows (or tests) manager_ip = cloudify_utils.get_manager_rest_service_host() self['rest_host'] = manager_ip self['broker_ip'] = manager_ip
def download(self, url, output_path=None, **attributes): """ Downloads the contents of the url. Following heuristic will be applied: 1. Try downloading with 'wget' command 2. if failed, try downloading with 'curl' command 3. if failed, raise a NonRecoverableError :param url: URL to the resource. :param output_path: Path where the resource will be downloaded to. If not specified, a temporary file will be used. :param attributes: custom attributes passed directly to fabric's run command :return: the output path. """ if output_path is None: output_path = self.mktemp() try: self.logger.debug('Attempting to locate wget on the host ' 'machine') self.run('which wget', **attributes) command = 'wget -T 30 {0} -O {1}'.format(url, output_path) except CommandExecutionException: try: self.logger.debug( 'wget not found. Attempting to locate cURL on the host ' 'machine') self.run('which curl', **attributes) command = 'curl {0} -o {1}'.format(url, output_path) except CommandExecutionException: raise exceptions.AgentInstallerConfigurationError( 'Cannot find neither wget nor curl'.format(url)) self.run(command, **attributes) return output_path
def connection_attributes(cloudify_agent): if 'local' not in cloudify_agent: cloudify_agent['local'] = ctx.type == context.DEPLOYMENT if cloudify_agent['local']: # if installing an agent locally, we auto-detect which # os the agent is dedicated for cloudify_agent['windows'] = os.name == 'nt' # if installing locally, we install the agent with the same user the # current agent is running under. we don't care about any other # connection details cloudify_agent['user'] = getpass.getuser() if 'remote_execution' not in cloudify_agent: cloudify_agent['remote_execution'] = True else: if 'remote_execution' not in cloudify_agent: install_method = cloudify_utils.internal.get_install_method( ctx.node.properties) if install_method not in constants.AGENT_INSTALL_METHODS: raise exceptions.AgentInstallerConfigurationError( 'agent_config.install_method must be one of {0}' ' but found: {1}'.format(constants.AGENT_INSTALL_METHODS, install_method)) remote_execution = ( install_method == constants.AGENT_INSTALL_METHOD_REMOTE) cloudify_agent.update({ 'remote_execution': remote_execution, 'install_method': install_method }) if 'windows' not in cloudify_agent: if ctx.plugin == 'windows_agent_installer': # 3.2 Compute node, installing windows cloudify_agent['windows'] = True elif ctx.plugin == 'agent_installer': # 3.2 Compute node, installing linux cloudify_agent['windows'] = False else: # 3.3 Compute node, determine by new property 'os_family' cloudify_agent['windows'] = ctx.node.properties[ 'os_family'].lower() == 'windows' # support 'ip' attribute as direct node property or runtime # property (as opposed to nested inside the cloudify_agent dict) ip = ctx.instance.runtime_properties.get('ip') if not ip: ip = ctx.node.properties.get('ip') if not ip: ip = cloudify_agent.get('ip') if not ip and cloudify_agent['remote_execution']: # a remote installation requires the ip to connect to. raise_missing_attribute('ip') if ip: cloudify_agent['ip'] = ip # support password as direct node property or runtime # property (as opposed to nested inside the cloudify_agent dict) password = ctx.instance.runtime_properties.get('password') if not password: password = ctx.node.properties.get('password') if not password: password = cloudify_agent.get('password') if not password and cloudify_agent['windows'] \ and cloudify_agent['remote_execution']: # a remote windows installation requires a # password to connect to the machine raise_missing_attribute('password') if password: cloudify_agent['password'] = password # a remote installation requires the username # that the agent will run under. if not cloudify_agent.get('user'): raise_missing_attribute('user') # a remote linux installation requires either a password or a key file # in order to connect to the remote machine. if not cloudify_agent['windows'] and \ not cloudify_agent.get('password') and \ not cloudify_agent.get('key') and \ cloudify_agent['remote_execution']: raise_missing_attributes('key', 'password')
def raise_missing_attributes(*attributes): raise exceptions.AgentInstallerConfigurationError( '{0} must be set in one of the following:\n{1}'.format( ' or '.join(attributes), _create_configuration_options()))