def __log_api_diff(self, api_diff):
        text_list = []
        for api, diff in api_diff.items():
            added = diff.to_instances_added()
            removed = diff.to_instances_removed()
            if not (added or removed):
                continue
            text_list.append(api + " Changes:")
            if added:
                text_list.append("+ ADDED:")
                for resource, instances in added.items():
                    text_list.append("  %s" % resource)
                    text_list.extend(
                        ["  - {!r}".format(name) for name in instances])

            if removed:
                text_list.append("- REMOVED:")
                for resource, instances in removed.items():
                    text_list.append("  %s" % resource)
                    text_list.extend(
                        ["  - {!r}".format(name) for name in instances])

        self.__to_log_path(
            "--- RESOURCES ---",
            detail="\n".join(text_list) if text_list else "None",
            indent=2,
        )

        if text_list:
            JournalLogger.journal_or_log_detail("GCP Resource Impact",
                                                "\n".join(text_list),
                                                format="pre")
        else:
            logging.info("No GCP resource impact")
Esempio n. 2
0
  def new_native_instance(cls, name, status_factory, base_url):
    """Create a new Spinnaker HttpAgent talking to the specified server port.

    Args:
      name: [string] The name of agent we are creating for reporting only.
      status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
         Factory method for creating specialized SpinnakerStatus instances.
      base_url: [string] The service base URL to send messages to.

    Returns:
      A SpinnakerAgent connected to the specified instance port.
    """
    logger = logging.getLogger(__name__)
    logger.info('Locating %s...', name)
    if not base_url:
      logger.error('Could not locate %s.', name)
      return None

    logger.info('%s is available at %s', name, base_url)
    env_url = os.path.join(base_url, 'resolvedEnv')
    deployed_config = scrape_spring_config(env_url)
    JournalLogger.journal_or_log_detail(
        '{0} configuration'.format(name), deployed_config)

    spinnaker_agent = cls(base_url, status_factory)
    spinnaker_agent.__deployed_config = deployed_config

    return spinnaker_agent
Esempio n. 3
0
  def new_native_instance(cls, name, status_factory, base_url):
    """Create a new Spinnaker HttpAgent talking to the specified server port.

    Args:
      name: [string] The name of agent we are creating for reporting only.
      status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
         Factory method for creating specialized SpinnakerStatus instances.
      base_url: [string] The service base URL to send messages to.

    Returns:
      A SpinnakerAgent connected to the specified instance port.
    """
    logger = logging.getLogger(__name__)
    logger.info('Locating %s...', name)
    if not base_url:
      logger.error('Could not locate %s.', name)
      return None

    logger.info('%s is available at %s', name, base_url)
    env_url = os.path.join(base_url, 'resolvedEnv')
    deployed_config = scrape_spring_config(env_url)
    JournalLogger.journal_or_log_detail(
        '{0} configuration'.format(name), deployed_config)

    spinnaker_agent = cls(base_url, status_factory)
    spinnaker_agent.__deployed_config = deployed_config

    return spinnaker_agent
  def __log_api_diff(self, api_diff):
    text_list = []
    for api, diff in api_diff.items():
      added = diff.to_instances_added()
      removed = diff.to_instances_removed()
      if not (added or removed):
        continue
      text_list.append(api + ' Changes:')
      if added:
        text_list.append('+ ADDED:')
        for resource, instances in added.items():
          text_list.append('  %s' % resource)
          text_list.extend(['  - {!r}'.format(name) for name in instances])

      if removed:
        text_list.append('- REMOVED:')
        for resource, instances in removed.items():
          text_list.append('  %s' % resource)
          text_list.extend(['  - {!r}'.format(name) for name in instances])

    self.__to_log_path('--- RESOURCES ---',
                       detail='\n'.join(text_list) if text_list else 'None',
                       indent=2)

    if text_list:
      JournalLogger.journal_or_log_detail(
          'GCP Resource Impact', '\n'.join(text_list), format='pre')
    else:
      logging.info('No GCP resource impact')
    def __log_delta_quota(self, before, after):
        if before == after:
            logging.info("No GCP quota impact.")
            return

        diff = {}
        for region in after.keys():
            before_quota = before.get(region, {})
            after_quota = after.get(region, {})
            if before_quota == after_quota:
                continue
            delta = {
                metric: after_quota[metric] - before_quota[metric]
                for metric in after_quota.keys()
                if after_quota.get(metric) != before_quota.get(metric)
            }
            if delta:
                diff[region] = delta

        self.__update_running_quota(diff)
        self.__to_log_path(
            "--- QUOTA ---",
            detail=json.JSONEncoder(indent=2,
                                    separators=(",", ": ")).encode(diff),
            indent=2,
        )
        JournalLogger.journal_or_log_detail("GCP Quota Impact",
                                            str(diff),
                                            format="json")
Esempio n. 6
0
  def __log_api_diff(self, api_diff):
    text_list = []
    for api, diff in api_diff.items():
      added = diff.to_instances_added()
      removed = diff.to_instances_removed()
      if not (added or removed):
        continue
      text_list.append(api + ' Changes:')
      if added:
        text_list.append('+ ADDED:')
        for resource, instances in added.items():
          text_list.append('  %s' % resource)
          text_list.extend(['  - {!r}'.format(name) for name in instances])

      if removed:
        text_list.append('- REMOVED:')
        for resource, instances in removed.items():
          text_list.append('  %s' % resource)
          text_list.extend(['  - {!r}'.format(name) for name in instances])

    self.__to_log_path('--- RESOURCES ---',
                       detail='\n'.join(text_list) if text_list else 'None',
                       indent=2)

    if text_list:
      JournalLogger.journal_or_log_detail(
          'GCP Resource Impact', '\n'.join(text_list), format='pre')
    else:
      logging.info('No GCP resource impact')
Esempio n. 7
0
  def new_gce_instance_from_bindings(
      cls, name, status_factory, bindings, port):
    """Create a new Spinnaker HttpAgent talking to the specified server port.

    Args:
      name: [string] The name of agent we are creating for reporting only.
      status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
         Factory method for creating specialized SpinnakerStatus instances.
      bindings: [dict] List of bindings to configure the endpoint
          GCE_PROJECT: The GCE project ID that the endpoint is in.
          GCE_ZONE: The GCE zone that the endpoint is in.
          GCE_INSTANCE: The GCE instance that the endpoint is in.
          GCE_SSH_PASSPHRASE_FILE: If not empty, the SSH passphrase key
              for tunneling if needed to connect through a GCE firewall.
          GCE_SERVICE_ACCOUNT: If not empty, the GCE service account to use
              when interacting with the GCE instance.
      port: [int] The port of the endpoint we want to connect to.
    Returns:
      A SpinnakerAgent connected to the specified instance port.
    """
    project = bindings['GCE_PROJECT']
    zone = bindings['GCE_ZONE']
    instance = bindings['GCE_INSTANCE']
    ssh_passphrase_file = bindings.get('GCE_SSH_PASSPHRASE_FILE', None)
    service_account = bindings.get('GCE_SERVICE_ACCOUNT', None)

    logger = logging.getLogger(__name__)
    JournalLogger.begin_context('Locating {0}...'.format(name))
    context_relation = 'ERROR'
    try:
      gcloud = gcp.GCloudAgent(
          project=project, zone=zone, service_account=service_account,
          ssh_passphrase_file=ssh_passphrase_file)
      netloc = gce_util.establish_network_connectivity(
          gcloud=gcloud, instance=instance, target_port=port)
      if not netloc:
        error = 'Could not locate {0}.'.format(name)
        logger.error(error)
        context_relation = 'INVALID'
        raise RuntimeError(error)

      protocol = bindings['NETWORK_PROTOCOL']
      base_url = '{protocol}://{netloc}'.format(protocol=protocol,
                                                netloc=netloc)
      logger.info('%s is available at %s. Using %s', name, netloc, base_url)
      deployed_config = scrape_spring_config(
          os.path.join(base_url, 'resolvedEnv'))
      JournalLogger.journal_or_log_detail(
          '{0} configuration'.format(name), deployed_config)
      spinnaker_agent = cls(base_url, status_factory)
      spinnaker_agent.__deployed_config = deployed_config
      context_relation = 'VALID'
    except:
      logger.exception('Failed to create spinnaker agent.')
      raise
    finally:
      JournalLogger.end_context(relation=context_relation)

    return spinnaker_agent
Esempio n. 8
0
    def run(self, args, trace=True, output_scrubber=None):
        """Run the specified command.

    Args:
      args: The list of command-line arguments for self.__program.
      trace: If True then we should trace the call/response.

    Returns:
      CliResponseType tuple containing program execution results.
    """
        command = self._args_to_full_commandline(args)
        log_msg = 'spawn {0} "{1}"'.format(command[0], '" "'.join(command[1:]))
        JournalLogger.journal_or_log(log_msg,
                                     _module=self.logger.name,
                                     _alwayslog=trace,
                                     _context='request')

        process = subprocess.Popen(command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   close_fds=True)
        stdout, stderr = process.communicate()

        scrubber = output_scrubber or self.__output_scrubber
        if scrubber:
            log_msg = 'Scrubbing output with {0}'.format(
                scrubber.__class__.__name__)
            JournalLogger.journal_or_log(log_msg,
                                         _module=self.logger.name,
                                         _alwayslog=trace)
            stdout = scrubber(stdout)

        # Strip leading/trailing eolns that program may add to errors and output.
        stderr = stderr.strip()
        stdout = stdout.strip()
        code = process.returncode

        # Always log to journal
        if stdout and stderr:
            which = 'both stdout and stderr'
            output_json = {'stdout': stdout, 'stderr': stderr}
        else:
            which = 'stderr' if stderr else 'stdout'
            output_json = stderr if stderr else stdout
        if output_json:
            JournalLogger.journal_or_log_detail('Result Code {0} / {1}'.format(
                code, which),
                                                output_json,
                                                _module=self.logger.name,
                                                _alwayslog=trace,
                                                _context='response')
        else:
            JournalLogger.journal_or_log(
                'Result Code {0} / no ouptut'.format(code),
                _module=self.logger.name,
                _alwayslog=trace,
                _context='response')

        return CliResponseType(code, stdout, stderr)
Esempio n. 9
0
  def new_gce_instance_from_bindings(
      cls, name, status_factory, bindings, port):
    """Create a new Spinnaker HttpAgent talking to the specified server port.

    Args:
      name: [string] The name of agent we are creating for reporting only.
      status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
         Factory method for creating specialized SpinnakerStatus instances.
      bindings: [dict] List of bindings to configure the endpoint
          GCE_PROJECT: The GCE project ID that the endpoint is in.
          GCE_ZONE: The GCE zone that the endpoint is in.
          GCE_INSTANCE: The GCE instance that the endpoint is in.
          GCE_SSH_PASSPHRASE_FILE: If not empty, the SSH passphrase key
              for tunneling if needed to connect through a GCE firewall.
          GCE_SERVICE_ACCOUNT: If not empty, the GCE service account to use
              when interacting with the GCE instance.
      port: [int] The port of the endpoint we want to connect to.
    Returns:
      A SpinnakerAgent connected to the specified instance port.
    """
    project = bindings['GCE_PROJECT']
    zone = bindings['GCE_ZONE']
    instance = bindings['GCE_INSTANCE']
    ssh_passphrase_file = bindings.get('GCE_SSH_PASSPHRASE_FILE', None)
    service_account = bindings.get('GCE_SERVICE_ACCOUNT', None)

    logger = logging.getLogger(__name__)
    JournalLogger.begin_context('Locating {0}...'.format(name))
    context_relation = 'ERROR'
    try:
      gcloud = gcp.GCloudAgent(
          project=project, zone=zone, service_account=service_account,
          ssh_passphrase_file=ssh_passphrase_file)
      netloc = gce_util.establish_network_connectivity(
          gcloud=gcloud, instance=instance, target_port=port)
      if not netloc:
        error = 'Could not locate {0}.'.format(name)
        logger.error(error)
        context_relation = 'INVALID'
        raise RuntimeError(error)

      protocol = bindings['NETWORK_PROTOCOL']
      base_url = '{protocol}://{netloc}'.format(protocol=protocol,
                                                netloc=netloc)
      logger.info('%s is available at %s. Using %s', name, netloc, base_url)
      deployed_config = scrape_spring_config(
          os.path.join(base_url, 'resolvedEnv'))
      JournalLogger.journal_or_log_detail(
          '{0} configuration'.format(name), deployed_config)
      spinnaker_agent = cls(base_url, status_factory)
      spinnaker_agent.__deployed_config = deployed_config
      context_relation = 'VALID'
    except:
      logger.exception('Failed to create spinnaker agent.')
      raise
    finally:
      JournalLogger.end_context(relation=context_relation)

    return spinnaker_agent
Esempio n. 10
0
  def run(self, args, output_scrubber=None):
    """Run the specified command.

    Args:
      args: The list of command-line arguments for self.__program.

    Returns:
      CliResponseType tuple containing program execution results.
    """
    command = self._args_to_full_commandline(args)
    log_msg = 'spawn {0} "{1}"'.format(command[0], '" "'.join(command[1:]))
    JournalLogger.journal_or_log(log_msg,
                                 _logger=self.logger,
                                 _context='request')

    process = subprocess.Popen(
        command,
        stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
    stdout, stderr = process.communicate()
    if stdout is not None:
      stdout = bytes.decode(stdout)
    if stderr is not None:
      stderr = bytes.decode(stderr)
    scrubber = output_scrubber or self.__output_scrubber
    if scrubber:
      log_msg = 'Scrubbing output with {0}'.format(scrubber.__class__.__name__)
      JournalLogger.journal_or_log(log_msg, _logger=self.logger)
      stdout = scrubber(stdout)

    # Strip leading/trailing eolns that program may add to errors and output.
    stderr = stderr.strip()
    stdout = stdout.strip()
    code = process.returncode

    # Always log to journal
    if stdout and stderr:
      which = 'both stdout and stderr'
      output_json = {'stdout':stdout, 'stderr':stderr}
    else:
      which = 'stderr' if stderr else 'stdout'
      output_json = stderr if stderr else stdout
    if output_json:
      JournalLogger.journal_or_log_detail(
          'Result Code {0} / {1}'.format(code, which), output_json,
          _logger=self.logger, _context='response')
    else:
      JournalLogger.journal_or_log(
          'Result Code {0} / no ouptut'.format(code),
          _logger=self.logger,
          _context='response')

    return CliResponseType(code, stdout, stderr)
Esempio n. 11
0
    def new_native_instance(cls, name, status_factory, base_url, bindings):
        """Create a new Spinnaker HttpAgent talking to the specified server port.

        Args:
          name: [string] The name of agent we are creating for reporting only.
          status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
             Factory method for creating specialized SpinnakerStatus instances.
          base_url: [string] The service base URL to send messages to.
          bindings: [dict] List of bindings to configure the endpoint
              BEARER_AUTH_TOKEN: The token used to authenticate request to a
                  protected host.
              IGNORE_SSL_CERT_VERIFICATION: If True, ignores SSL certificate
                  verification when making requests.
        Returns:
          A SpinnakerAgent connected to the specified instance port.
        """
        bearer_auth_token = bindings.get("BEARER_AUTH_TOKEN", None)
        ignore_ssl_cert_verification = bindings["IGNORE_SSL_CERT_VERIFICATION"]

        logger = logging.getLogger(__name__)
        logger.info("Locating %s...", name)
        if not base_url:
            logger.error("Could not locate %s.", name)
            return None

        logger.info("%s is available at %s", name, base_url)
        env_url = os.path.join(base_url, "resolvedEnv")
        headers = {}
        if bearer_auth_token:
            headers["Authorization"] = "Bearer {}".format(bearer_auth_token)
        deployed_config = scrape_spring_config(
            env_url,
            headers=headers,
            ignore_ssl_cert_verification=ignore_ssl_cert_verification,
        )
        JournalLogger.journal_or_log_detail(
            "{0} configuration".format(name), deployed_config
        )

        spinnaker_agent = cls(base_url, status_factory)
        spinnaker_agent.ignore_ssl_cert_verification = ignore_ssl_cert_verification
        spinnaker_agent.__deployed_config = deployed_config

        if bearer_auth_token:
            spinnaker_agent.add_header(
                "Authorization", "Bearer {}".format(bearer_auth_token)
            )

        return spinnaker_agent
Esempio n. 12
0
  def new_native_instance(cls, name, status_factory, base_url, bindings):
    """Create a new Spinnaker HttpAgent talking to the specified server port.

    Args:
      name: [string] The name of agent we are creating for reporting only.
      status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
         Factory method for creating specialized SpinnakerStatus instances.
      base_url: [string] The service base URL to send messages to.
      bindings: [dict] List of bindings to configure the endpoint
          BEARER_AUTH_TOKEN: The token used to authenticate request to a
              protected host.
          IGNORE_SSL_CERT_VERIFICATION: If True, ignores SSL certificate
              verification when making requests.
    Returns:
      A SpinnakerAgent connected to the specified instance port.
    """
    bearer_auth_token = bindings.get('BEARER_AUTH_TOKEN', None)
    ignore_ssl_cert_verification = bindings['IGNORE_SSL_CERT_VERIFICATION']

    logger = logging.getLogger(__name__)
    logger.info('Locating %s...', name)
    if not base_url:
      logger.error('Could not locate %s.', name)
      return None

    logger.info('%s is available at %s', name, base_url)
    env_url = os.path.join(base_url, 'resolvedEnv')
    headers = {}
    if bearer_auth_token:
      headers['Authorization'] = 'Bearer {}'.format(bearer_auth_token)
    deployed_config = scrape_spring_config(env_url, headers=headers, ignore_ssl_cert_verification=ignore_ssl_cert_verification)
    JournalLogger.journal_or_log_detail(
        '{0} configuration'.format(name), deployed_config)

    spinnaker_agent = cls(base_url, status_factory)
    spinnaker_agent.ignore_ssl_cert_verification = ignore_ssl_cert_verification
    spinnaker_agent.__deployed_config = deployed_config

    if bearer_auth_token:
      spinnaker_agent.add_header('Authorization', 'Bearer {}'.format(bearer_auth_token))

    return spinnaker_agent
Esempio n. 13
0
  def new_native_instance(cls, name, status_factory, base_url, bindings):
    """Create a new Spinnaker HttpAgent talking to the specified server port.

    Args:
      name: [string] The name of agent we are creating for reporting only.
      status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
         Factory method for creating specialized SpinnakerStatus instances.
      base_url: [string] The service base URL to send messages to.
      bindings: [dict] List of bindings to configure the endpoint
          BEARER_AUTH_TOKEN: The token used to authenticate request to a
              protected host.
    Returns:
      A SpinnakerAgent connected to the specified instance port.
    """
    bearer_auth_token = bindings.get('BEARER_AUTH_TOKEN', None)

    logger = logging.getLogger(__name__)
    logger.info('Locating %s...', name)
    if not base_url:
      logger.error('Could not locate %s.', name)
      return None

    logger.info('%s is available at %s', name, base_url)
    env_url = os.path.join(base_url, 'resolvedEnv')
    deployed_config = scrape_spring_config(env_url, headers={
      'Authorization': 'Bearer {}'.format(bearer_auth_token)
    })
    JournalLogger.journal_or_log_detail(
        '{0} configuration'.format(name), deployed_config)

    spinnaker_agent = cls(base_url, status_factory)
    spinnaker_agent.__deployed_config = deployed_config

    if bearer_auth_token:
      spinnaker_agent.add_header('Authorization', 'Bearer {}'.format(bearer_auth_token))

    return spinnaker_agent
  def __log_delta_quota(self, before, after):
    if before == after:
      logging.info('No GCP quota impact.')
      return

    diff = {}
    for region in after.keys():
      before_quota = before.get(region, {})
      after_quota = after.get(region, {})
      if before_quota == after_quota:
        continue
      delta = {metric: after_quota[metric] - before_quota[metric]
               for metric in after_quota.keys()
               if after_quota.get(metric) != before_quota.get(metric)}
      if delta:
        diff[region] = delta

    self.__update_running_quota(diff)
    self.__to_log_path(
        '--- QUOTA ---',
        detail=json.JSONEncoder(indent=2, separators=(',', ': ')).encode(diff),
        indent=2)
    JournalLogger.journal_or_log_detail('GCP Quota Impact',
                                        str(diff), format='json')
Esempio n. 15
0
    def __send_http_request(self, path, http_type, data=None, headers=None):
        """Send an HTTP message.

    Args:
      path: [string] The URL path to send to (without network location)
      http_type: [string] The HTTP message type (e.g. POST)
      data: [string] Data payload to send, if any.
      headers: [dict] Headers to write, if any.

    Returns:
      HttpResponseType
    """
        if headers is None:
            all_headers = self.__headers
        else:
            all_headers = self.__headers.copy()
            all_headers.update(headers)

        if path[0] == '/':
            path = path[1:]
        url = '{0}/{1}'.format(self.__base_url, path)

        req = urllib2.Request(url=url, data=data, headers=all_headers)
        req.get_method = lambda: http_type

        scrubbed_url = self.__http_scrubber.scrub_url(url)
        scrubbed_data = self.__http_scrubber.scrub_request(data)

        if data is not None:
            JournalLogger.journal_or_log_detail('{type} {url}'.format(
                type=http_type, url=scrubbed_url),
                                                scrubbed_data,
                                                _logger=self.logger,
                                                _context='request')
        else:
            JournalLogger.journal_or_log('{type} {url}'.format(
                type=http_type, url=scrubbed_url),
                                         _logger=self.logger,
                                         _context='request')

        code = None
        output = None
        exception = None
        try:
            response = urllib2.urlopen(req)
            code = response.getcode()
            output = response.read()

            scrubbed_output = self.__http_scrubber.scrub_response(output)
            JournalLogger.journal_or_log_detail(
                'HTTP {code}'.format(code=code),
                scrubbed_output,
                _logger=self.logger,
                _context='response')

        except urllib2.HTTPError as ex:
            code = ex.getcode()
            output = ex.read()
            scrubbed_error = self.__http_scrubber.scrub_response(output)
            JournalLogger.journal_or_log_detail(
                'HTTP {code}'.format(code=code),
                scrubbed_error,
                _logger=self.logger,
                _context='response')

        except urllib2.URLError as ex:
            JournalLogger.journal_or_log(
                'Caught exception: {ex}\n{stack}'.format(
                    ex=ex, stack=traceback.format_exc()),
                _logger=self.logger)
            exception = ex
        return HttpResponseType(code, output, exception)
Esempio n. 16
0
  def __send_http_request(self, path, http_type, data=None, headers=None):
    """Send an HTTP message.

    Args:
      path: [string] The URL path to send to (without network location)
      http_type: [string] The HTTP message type (e.g. POST)
      data: [string] Data payload to send, if any.
      headers: [dict] Headers to write, if any.

    Returns:
      HttpResponseType
    """
    if headers is None:
      all_headers = self.__headers
    else:
      all_headers = self.__headers.copy()
      all_headers.update(headers)

    if path[0] == '/':
      path = path[1:]
    url = '{0}/{1}'.format(self.__base_url, path)

    encoded_data = str.encode(data) if data is not None else None
    req = Request(url=url, data=encoded_data, headers=all_headers)
    req.get_method = lambda: http_type

    scrubbed_url = self.__http_scrubber.scrub_url(url)
    scrubbed_data = self.__http_scrubber.scrub_request(data)

    if data is not None:
      JournalLogger.journal_or_log_detail(
          '{type} {url}'.format(type=http_type, url=scrubbed_url),
          scrubbed_data,
          _logger=self.logger,
          _context='request')
    else:
      JournalLogger.journal_or_log(
          '{type} {url}'.format(type=http_type, url=scrubbed_url),
          _logger=self.logger,
          _context='request')

    if self.__ignore_ssl_cert_verification:
      context = ssl._create_unverified_context()
      opener = build_opener(HTTPSHandler(context=context), HTTPCookieProcessor())
    else:
      opener = build_opener(HTTPCookieProcessor())

    code = None
    output = None
    exception = None
    headers = None

    try:
      response = opener.open(req)
      code = response.getcode()
      output = bytes.decode(response.read())
      if sys.version_info[0] > 2:
        headers = dict(response.headers.items())
      else:
        headers = response.info().headers

      scrubbed_output = self.__http_scrubber.scrub_response(output)
      JournalLogger.journal_or_log_detail(
          'HTTP {code}'.format(code=code),
          scrubbed_output,
          _logger=self.logger,
          _context='response')

    except HTTPError as ex:
      code = ex.getcode()
      output = bytes.decode(ex.read())
      scrubbed_error = self.__http_scrubber.scrub_response(output)
      JournalLogger.journal_or_log_detail(
          'HTTP {code}'.format(code=code), scrubbed_error,
          _logger=self.logger,
          _context='response')

    except URLError as ex:
      JournalLogger.journal_or_log(
          'Caught exception: {ex}\n{stack}'.format(
              ex=ex, stack=traceback.format_exc()),
          _logger=self.logger)
      exception = ex
    return HttpResponseType(http_code=code, output=output,
                            exception=exception, headers=headers)
Esempio n. 17
0
  def __send_http_request(self, path, http_type, data=None, headers=None):
    """Send an HTTP message.

    Args:
      path: [string] The URL path to send to (without network location)
      http_type: [string] The HTTP message type (e.g. POST)
      data: [string] Data payload to send, if any.
      headers: [dict] Headers to write, if any.

    Returns:
      HttpResponseType
    """
    if headers is None:
      all_headers = self.__headers
    else:
      all_headers = self.__headers.copy()
      all_headers.update(headers)

    if path[0] == '/':
      path = path[1:]
    url = '{0}/{1}'.format(self.__base_url, path)

    encoded_data = str.encode(data) if data is not None else None
    req = Request(url=url, data=encoded_data, headers=all_headers)
    req.get_method = lambda: http_type

    scrubbed_url = self.__http_scrubber.scrub_url(url)
    scrubbed_data = self.__http_scrubber.scrub_request(data)

    if data is not None:
      JournalLogger.journal_or_log_detail(
          '{type} {url}'.format(type=http_type, url=scrubbed_url),
          scrubbed_data,
          _logger=self.logger,
          _context='request')
    else:
      JournalLogger.journal_or_log(
          '{type} {url}'.format(type=http_type, url=scrubbed_url),
          _logger=self.logger,
          _context='request')

    if self.__ignore_ssl_cert_verification:
      context = ssl._create_unverified_context()
      opener = build_opener(HTTPSHandler(context=context), HTTPCookieProcessor())
    else:
      opener = build_opener(HTTPCookieProcessor())

    code = None
    output = None
    exception = None
    headers = None

    try:
      response = opener.open(req)
      code = response.getcode()
      output = bytes.decode(response.read())
      if sys.version_info[0] > 2:
        headers = dict(response.headers.items())
      else:
        headers = response.info().headers

      scrubbed_output = self.__http_scrubber.scrub_response(output)
      JournalLogger.journal_or_log_detail(
          'HTTP {code}'.format(code=code),
          scrubbed_output,
          _logger=self.logger,
          _context='response')

    except HTTPError as ex:
      code = ex.getcode()
      output = bytes.decode(ex.read())
      scrubbed_error = self.__http_scrubber.scrub_response(output)
      JournalLogger.journal_or_log_detail(
          'HTTP {code}'.format(code=code), scrubbed_error,
          _logger=self.logger,
          _context='response')

    except URLError as ex:
      JournalLogger.journal_or_log(
          'Caught exception: {ex}\n{stack}'.format(
              ex=ex, stack=traceback.format_exc()),
          _logger=self.logger)
      exception = ex
    return HttpResponseType(http_code=code, output=output,
                            exception=exception, headers=headers)
Esempio n. 18
0
    def new_gce_instance_from_bindings(cls, name, status_factory, bindings, port):
        """Create a new Spinnaker HttpAgent talking to the specified server port.

        Args:
          name: [string] The name of agent we are creating for reporting only.
          status_factory: [SpinnakerStatus (SpinnakerAgent, HttpResponseType)]
             Factory method for creating specialized SpinnakerStatus instances.
          bindings: [dict] List of bindings to configure the endpoint
              GCE_PROJECT: The GCE project ID that the endpoint is in.
              GCE_ZONE: The GCE zone that the endpoint is in.
              GCE_INSTANCE: The GCE instance that the endpoint is in.
              GCE_SSH_PASSPHRASE_FILE: If not empty, the SSH passphrase key
                  for tunneling if needed to connect through a GCE firewall.
              GCE_SERVICE_ACCOUNT: If not empty, the GCE service account to use
                  when interacting with the GCE instance.
              IGNORE_SSL_CERT_VERIFICATION: If True, ignores SSL certificate
                  verification when scraping spring config.
          port: [int] The port of the endpoint we want to connect to.
        Returns:
          A SpinnakerAgent connected to the specified instance port.
        """
        project = bindings["GCE_PROJECT"]
        zone = bindings["GCE_ZONE"]
        instance = bindings["GCE_INSTANCE"]
        ssh_passphrase_file = bindings.get("GCE_SSH_PASSPHRASE_FILE", None)
        service_account = bindings.get("GCE_SERVICE_ACCOUNT", None)
        ignore_ssl_cert_verification = bindings["IGNORE_SSL_CERT_VERIFICATION"]

        logger = logging.getLogger(__name__)
        JournalLogger.begin_context("Locating {0}...".format(name))
        context_relation = "ERROR"
        try:
            gcloud = gcp.GCloudAgent(
                project=project,
                zone=zone,
                service_account=service_account,
                ssh_passphrase_file=ssh_passphrase_file,
            )
            netloc = gce_util.establish_network_connectivity(
                gcloud=gcloud, instance=instance, target_port=port
            )
            if not netloc:
                error = "Could not locate {0}.".format(name)
                logger.error(error)
                context_relation = "INVALID"
                raise RuntimeError(error)

            protocol = bindings["NETWORK_PROTOCOL"]
            base_url = "{protocol}://{netloc}".format(protocol=protocol, netloc=netloc)
            logger.info("%s is available at %s. Using %s", name, netloc, base_url)
            deployed_config = scrape_spring_config(
                os.path.join(base_url, "resolvedEnv"),
                ignore_ssl_cert_verification=ignore_ssl_cert_verification,
            )
            JournalLogger.journal_or_log_detail(
                "{0} configuration".format(name), deployed_config
            )
            spinnaker_agent = cls(base_url, status_factory)
            spinnaker_agent.__deployed_config = deployed_config
            context_relation = "VALID"
        except:
            logger.exception("Failed to create spinnaker agent.")
            raise
        finally:
            JournalLogger.end_context(relation=context_relation)

        return spinnaker_agent
Esempio n. 19
0
  def __send_http_request(self, path, http_type, data=None, headers=None):
    """Send an HTTP message.

    Args:
      path: [string] The URL path to send to (without network location)
      http_type: [string] The HTTP message type (e.g. POST)
      data: [string] Data payload to send, if any.
      headers: [dict] Headers to write, if any.

    Returns:
      HttpResponseType
    """
    if headers is None:
      all_headers = self.__headers
    else:
      all_headers = self.__headers.copy()
      all_headers.update(headers)

    if path[0] == '/':
      path = path[1:]
    url = '{0}/{1}'.format(self.__base_url, path)

    req = urllib2.Request(url=url, data=data, headers=all_headers)
    req.get_method = lambda: http_type

    scrubbed_url = self.__http_scrubber.scrub_url(url)
    scrubbed_data = self.__http_scrubber.scrub_request(data)

    if data is not None:
      JournalLogger.journal_or_log_detail(
          '{type} {url}'.format(type=http_type, url=scrubbed_url),
          scrubbed_data,
          _logger=self.logger,
          _context='request')
    else:
      JournalLogger.journal_or_log(
          '{type} {url}'.format(type=http_type, url=scrubbed_url),
          _logger=self.logger,
          _context='request')

    code = None
    output = None
    exception = None
    try:
      response = urllib2.urlopen(req)
      code = response.getcode()
      output = response.read()

      scrubbed_output = self.__http_scrubber.scrub_response(output)
      JournalLogger.journal_or_log_detail(
          'HTTP {code}'.format(code=code),
          scrubbed_output,
          _logger=self.logger,
          _context='response')

    except urllib2.HTTPError as ex:
      code = ex.getcode()
      output = ex.read()
      scrubbed_error = self.__http_scrubber.scrub_response(output)
      JournalLogger.journal_or_log_detail(
          'HTTP {code}'.format(code=code), scrubbed_error,
          _logger=self.logger,
          _context='response')

    except urllib2.URLError as ex:
      JournalLogger.journal_or_log(
          'Caught exception: {ex}\n{stack}'.format(
              ex=ex, stack=traceback.format_exc()),
          _logger=self.logger)
      exception = ex
    return HttpResponseType(code, output, exception)