github.com/pulumi/pulumi/sdk/v3@v3.108.1/nodejs/runtime/config.ts (about)

     1  // Copyright 2016-2018, Pulumi Corporation.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  import { getStore } from "./state";
    16  
    17  /**
    18   * configEnvKey is the environment variable key that the language plugin uses to set configuration values.
    19   *
    20   * @internal
    21   */
    22  export const configEnvKey = "PULUMI_CONFIG";
    23  
    24  /**
    25   * configSecretKeysEnvKey is the environment variable key that the language plugin uses to set configuration keys that
    26   * contain secrets.
    27   *
    28   * @internal
    29   */
    30  export const configSecretKeysEnvKey = "PULUMI_CONFIG_SECRET_KEYS";
    31  
    32  /**
    33   * allConfig returns a copy of the full config map.
    34   */
    35  export function allConfig(): { [key: string]: string } {
    36      const config = parseConfig();
    37      return Object.assign({}, config);
    38  }
    39  
    40  /**
    41   * setAllConfig overwrites the config map.
    42   */
    43  export function setAllConfig(c: { [key: string]: string }, secretKeys?: string[]) {
    44      const obj: { [key: string]: string } = {};
    45      for (const k of Object.keys(c)) {
    46          obj[cleanKey(k)] = c[k];
    47      }
    48      persistConfig(obj, secretKeys);
    49  }
    50  
    51  /**
    52   * setConfig sets a configuration variable.
    53   */
    54  export function setConfig(k: string, v: string): void {
    55      const config = parseConfig();
    56      config[cleanKey(k)] = v;
    57      persistConfig(config, []);
    58  }
    59  
    60  /**
    61   * getConfig returns a configuration variable's value or undefined if it is unset.
    62   */
    63  export function getConfig(k: string): string | undefined {
    64      const config = parseConfig();
    65      return config[k];
    66  }
    67  
    68  /**
    69   * isConfigSecret returns true if the key contains a secret value.
    70   * @internal
    71   */
    72  export function isConfigSecret(k: string): boolean {
    73      const { config } = getStore();
    74      const envConfigSecretKeys = config[configSecretKeysEnvKey];
    75      if (envConfigSecretKeys) {
    76          const envConfigSecretArray = JSON.parse(envConfigSecretKeys);
    77          if (Array.isArray(envConfigSecretArray)) {
    78              return envConfigSecretArray.includes(k);
    79          }
    80      }
    81      return false;
    82  }
    83  
    84  /**
    85   * parseConfig reads config from the source of truth, the environment.
    86   * config must always be read this way because automation api introduces
    87   * new program lifetime semantics where program lifetime != module lifetime.
    88   */
    89  function parseConfig() {
    90      const { config } = getStore();
    91      const parsedConfig: { [key: string]: string } = {};
    92      const envConfig = config[configEnvKey];
    93      if (envConfig) {
    94          const envObject: { [key: string]: string } = JSON.parse(envConfig);
    95          for (const k of Object.keys(envObject)) {
    96              parsedConfig[cleanKey(k)] = envObject[k];
    97          }
    98      }
    99  
   100      return parsedConfig;
   101  }
   102  
   103  /**
   104   * persistConfig writes config to the environment.
   105   * config changes must always be persisted to the environment because automation api introduces
   106   * new program lifetime semantics where program lifetime != module lifetime.
   107   */
   108  function persistConfig(config: { [key: string]: string }, secretKeys?: string[]) {
   109      const store = getStore();
   110      const serializedConfig = JSON.stringify(config);
   111      const serializedSecretKeys = Array.isArray(secretKeys) ? JSON.stringify(secretKeys) : "[]";
   112      store.config[configEnvKey] = serializedConfig;
   113      store.config[configSecretKeysEnvKey] = serializedSecretKeys;
   114  }
   115  
   116  /**
   117   * cleanKey takes a configuration key, and if it is of the form "<string>:config:<string>" removes
   118   * the ":config:" portion. Previously, our keys always had the string ":config:" in them, and we'd
   119   * like to remove it. However, the language host needs to continue to set it so we can be compatible
   120   * with older versions of our packages. Once we stop supporting older packages, we can change the
   121   * language host to not add this :config: thing and remove this function.
   122   */
   123  function cleanKey(key: string): string {
   124      const idx = key.indexOf(":");
   125  
   126      if (idx > 0 && key.startsWith("config:", idx + 1)) {
   127          return key.substring(0, idx) + ":" + key.substring(idx + 1 + "config:".length);
   128      }
   129  
   130      return key;
   131  }