public static Properties setIAMProperties()

in src/main/java/com/amazon/redshift/core/IamHelper.java [105:359]


  public static Properties setIAMProperties(Properties info, RedshiftJDBCSettings settings, RedshiftLogger log)
      throws RedshiftException {
    try {
      // IAM requires an SSL connection to work. Make sure that m_authMech is
      // set to
      // SSL level VERIFY_CA or higher.
      if (settings.m_authMech == null || settings.m_authMech.ordinal() < AuthMech.VERIFY_CA.ordinal()) {
        settings.m_authMech = AuthMech.VERIFY_CA;
      }

      // Check for IAM keys and AuthProfile first
      String iamAccessKey = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.IAM_ACCESS_KEY_ID.getName(),
          info);

      String iamSecretKey = RedshiftConnectionImpl
          .getOptionalConnSetting(RedshiftProperty.IAM_SECRET_ACCESS_KEY.getName(), info);

      String iamSessionToken = RedshiftConnectionImpl
          .getOptionalConnSetting(RedshiftProperty.IAM_SESSION_TOKEN.getName(), info);
      String authProfile = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.AUTH_PROFILE.getName(), info);

      if (!StringUtils.isNullOrEmpty(authProfile)) {
        if (!StringUtils.isNullOrEmpty(iamAccessKey)) {
          Properties authProfileProps = readAuthProfile(authProfile, iamAccessKey, iamSecretKey, iamSessionToken, log,
              info);
          if (authProfileProps != null) {
            // Merge auth profile props with user props.
            // User props overrides auth profile props
            authProfileProps.putAll(info);
            info = authProfileProps;
          }
        } else {
          // Auth profile specified but IAM keys are not
          RedshiftException err = new RedshiftException(
              GT.tr("Dependent connection property setting for {0} is missing {1}",
                  RedshiftProperty.AUTH_PROFILE.getName(), RedshiftProperty.IAM_ACCESS_KEY_ID.getName()),
              RedshiftState.UNEXPECTED_ERROR);

          if (RedshiftLogger.isEnable())
            log.log(LogLevel.ERROR, err.toString());

          throw err;

        }

      } // AuthProfile

      String isServerless = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftConnectionImpl.IS_SERVERLESS, info);
      settings.m_isServerless = isServerless == null ? false : Boolean.valueOf(isServerless);

      String clusterId = (!settings.m_isServerless)
          ? RedshiftConnectionImpl.getRequiredConnSetting(RedshiftProperty.CLUSTER_IDENTIFIER.getName(), info) : null;
      String acctId = (settings.m_isServerless)
          ? RedshiftConnectionImpl.getOptionalConnSetting(RedshiftConnectionImpl.SERVERLESS_ACCT_ID, info) : null;
      String awsRegion = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.AWS_REGION.getName(), info);
      String endpointUrl = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.ENDPOINT_URL.getName(), info);
      String stsEndpointUrl = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.STS_ENDPOINT_URL.getName(),
          info);
      String userName = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.UID.getName(), info);
      if (userName == null)
        userName = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.USER.getName(), info);
      String password = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.PWD.getName(), info);
      if (password == null)
        password = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.PASSWORD.getName(), info);

      String profile = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.AWS_PROFILE.getName(), info);
      if (profile == null)
        profile = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.AWS_PROFILE.getName().toLowerCase(),
            info);
      String iamDuration = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.IAM_DURATION.getName(), info);

      String iamCredentialProvider = RedshiftConnectionImpl
          .getOptionalConnSetting(RedshiftProperty.CREDENTIALS_PROVIDER.getName(), info);

      String iamAutoCreate = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.USER_AUTOCREATE.getName(),
          info);
      String iamDbUser = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.DB_USER.getName(), info);
      String iamDbGroups = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.DB_GROUPS.getName(), info);
      String iamForceLowercase = RedshiftConnectionImpl
          .getOptionalConnSetting(RedshiftProperty.FORCE_LOWERCASE.getName(), info);
      String iamGroupFederation = RedshiftConnectionImpl
          .getOptionalConnSetting(RedshiftProperty.GROUP_FEDERATION.getName(), info);
      String dbName = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.DBNAME.getName(), info);

      String hosts = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.HOST.getName(), info);
      String ports = RedshiftConnectionImpl.getOptionalConnSetting(RedshiftProperty.PORT.getName(), info);
      String iamDisableCache = RedshiftConnectionImpl
          .getOptionalConnSetting(RedshiftProperty.IAM_DISABLE_CACHE.getName(), info);

      settings.m_clusterIdentifier = clusterId;

      if (!settings.m_isServerless && settings.m_clusterIdentifier.isEmpty()) {
        RedshiftException err = new RedshiftException(
            GT.tr("Missing connection property {0}", RedshiftProperty.CLUSTER_IDENTIFIER.getName()),
            RedshiftState.UNEXPECTED_ERROR);

        if (RedshiftLogger.isEnable())
          log.log(LogLevel.ERROR, err.toString());

        throw err;
      }

      if (settings.m_isServerless)
        settings.m_acctId = acctId;

      // Regions.fromName(string) requires the string to be lower case and in
      // this format:
      // E.g. "us-west-2"
      if (null != awsRegion) {
        settings.m_awsRegion = awsRegion.trim().toLowerCase();
      }

      if (null != endpointUrl) {
        settings.m_endpoint = endpointUrl;
      } else {
        settings.m_endpoint = System.getProperty("redshift.endpoint-url");
      }

      if (null != stsEndpointUrl) {
        settings.m_stsEndpoint = stsEndpointUrl;
      } else {
        settings.m_stsEndpoint = System.getProperty("sts.endpoint-url");
      }

      if (null != userName) {
        settings.m_username = userName;
      }

      if (null != password) {
        settings.m_password = password;
      }

      if (null != profile) {
        settings.m_profile = profile;
      }

      if (null != iamDuration) {
        try {
          settings.m_iamDuration = Integer.parseInt(iamDuration);
          if (settings.m_iamDuration < 900 || settings.m_iamDuration > 3600) {
            RedshiftException err = new RedshiftException(
                GT.tr("Invalid connection property value or type range(900-3600) {0}",
                    RedshiftProperty.IAM_DURATION.getName()),
                RedshiftState.UNEXPECTED_ERROR);

            if (RedshiftLogger.isEnable())
              log.log(LogLevel.ERROR, err.toString());

            throw err;
          }
        } catch (NumberFormatException e) {
          RedshiftException err = new RedshiftException(GT.tr("Invalid connection property value {0} : {1}",
              RedshiftProperty.IAM_DURATION.getName(), iamDuration), RedshiftState.UNEXPECTED_ERROR, e);

          if (RedshiftLogger.isEnable())
            log.log(LogLevel.DEBUG, err.toString());

          throw err;
        }
      }

      if (null != iamAccessKey) {
        settings.m_iamAccessKeyID = iamAccessKey;
      }

      // Because the secret access key should be hidden, and most applications
      // (for example:
      // SQL Workbench) only hide passwords, Amazon has requested that we allow
      // the
      // secret access key to be passed as either the IAMSecretAccessKey
      // property or
      // as a password value.
      if (null != iamSecretKey) {
        if (StringUtils.isNullOrEmpty(settings.m_iamAccessKeyID)) {
          RedshiftException err = new RedshiftException(
              GT.tr("Missing connection property {0}", RedshiftProperty.IAM_ACCESS_KEY_ID.getName()),
              RedshiftState.UNEXPECTED_ERROR);

          if (RedshiftLogger.isEnable())
            log.log(LogLevel.ERROR, err.toString());

          throw err;
        }

        settings.m_iamSecretKey = iamSecretKey;
        if (settings.m_iamSecretKey.isEmpty()) {
          settings.m_iamSecretKey = settings.m_password;
        }
      } else {
        settings.m_iamSecretKey = settings.m_password;
      }

      if (null != iamSessionToken) {
        if (StringUtils.isNullOrEmpty(settings.m_iamAccessKeyID)) {
          RedshiftException err = new RedshiftException(
              GT.tr("Missing connection property {0}", RedshiftProperty.IAM_ACCESS_KEY_ID.getName()),
              RedshiftState.UNEXPECTED_ERROR);

          if (RedshiftLogger.isEnable())
            log.log(LogLevel.ERROR, err.toString());
          throw err;
        }
        settings.m_iamSessionToken = iamSessionToken;
      }

      if (null != iamCredentialProvider) {
        settings.m_credentialsProvider = iamCredentialProvider;
      }

      Enumeration<String> enums = (Enumeration<String>) info.propertyNames();
      while (enums.hasMoreElements()) {
        // The given properties are String pairs, so this should be OK.
        String key = enums.nextElement();
        String value = info.getProperty(key);
        key = key.toLowerCase(Locale.getDefault());
        if (!"*".equals(value)) {
          settings.m_pluginArgs.put(key, value);
        }
      }

      settings.m_autocreate = iamAutoCreate == null ? null : Boolean.valueOf(iamAutoCreate);

      settings.m_iamDisableCache = iamDisableCache == null ? false : Boolean.valueOf(iamDisableCache);

      settings.m_forceLowercase = iamForceLowercase == null ? null : Boolean.valueOf(iamForceLowercase);

      settings.m_groupFederation = iamGroupFederation == null ? false : Boolean.valueOf(iamGroupFederation);

      if (null != iamDbUser) {
        settings.m_dbUser = iamDbUser;
      }

      settings.m_dbGroups = (iamDbGroups != null)
          ? Arrays.asList((settings.m_forceLowercase != null && settings.m_forceLowercase
              ? iamDbGroups.toLowerCase(Locale.getDefault()) : iamDbGroups).split(","))
          : Collections.<String>emptyList();

      settings.m_Schema = dbName;
      if (hosts != null) {
        settings.m_host = hosts;
      }
      if (ports != null) {
        settings.m_port = Integer.parseInt(ports);
      }

      setIAMCredentials(settings, log, authProfile);

      return info;
    } catch (RedshiftException re) {
      if (RedshiftLogger.isEnable())
        log.logError(re);

      throw re;
    }
  }