// Copyright 2016-2018, Pulumi Corporation. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { getStore } from "./state"; /** * configEnvKey is the environment variable key that the language plugin uses to set configuration values. * * @internal */ export const configEnvKey = "PULUMI_CONFIG"; /** * configSecretKeysEnvKey is the environment variable key that the language plugin uses to set configuration keys that * contain secrets. * * @internal */ export const configSecretKeysEnvKey = "PULUMI_CONFIG_SECRET_KEYS"; /** * allConfig returns a copy of the full config map. */ export function allConfig(): { [key: string]: string } { const config = parseConfig(); return Object.assign({}, config); } /** * setAllConfig overwrites the config map. */ export function setAllConfig(c: { [key: string]: string }, secretKeys?: string[]) { const obj: { [key: string]: string } = {}; for (const k of Object.keys(c)) { obj[cleanKey(k)] = c[k]; } persistConfig(obj, secretKeys); } /** * setConfig sets a configuration variable. */ export function setConfig(k: string, v: string): void { const config = parseConfig(); config[cleanKey(k)] = v; persistConfig(config, []); } /** * getConfig returns a configuration variable's value or undefined if it is unset. */ export function getConfig(k: string): string | undefined { const config = parseConfig(); return config[k]; } /** * isConfigSecret returns true if the key contains a secret value. * @internal */ export function isConfigSecret(k: string): boolean { const { config } = getStore(); const envConfigSecretKeys = config[configSecretKeysEnvKey]; if (envConfigSecretKeys) { const envConfigSecretArray = JSON.parse(envConfigSecretKeys); if (Array.isArray(envConfigSecretArray)) { return envConfigSecretArray.includes(k); } } return false; } /** * parseConfig reads config from the source of truth, the environment. * config must always be read this way because automation api introduces * new program lifetime semantics where program lifetime != module lifetime. */ function parseConfig() { const { config } = getStore(); const parsedConfig: { [key: string]: string } = {}; const envConfig = config[configEnvKey]; if (envConfig) { const envObject: { [key: string]: string } = JSON.parse(envConfig); for (const k of Object.keys(envObject)) { parsedConfig[cleanKey(k)] = envObject[k]; } } return parsedConfig; } /** * persistConfig writes config to the environment. * config changes must always be persisted to the environment because automation api introduces * new program lifetime semantics where program lifetime != module lifetime. */ function persistConfig(config: { [key: string]: string }, secretKeys?: string[]) { const store = getStore(); const serializedConfig = JSON.stringify(config); const serializedSecretKeys = Array.isArray(secretKeys) ? JSON.stringify(secretKeys) : "[]"; store.config[configEnvKey] = serializedConfig; store.config[configSecretKeysEnvKey] = serializedSecretKeys; } /** * cleanKey takes a configuration key, and if it is of the form "<string>:config:<string>" removes * the ":config:" portion. Previously, our keys always had the string ":config:" in them, and we'd * like to remove it. However, the language host needs to continue to set it so we can be compatible * with older versions of our packages. Once we stop supporting older packages, we can change the * language host to not add this :config: thing and remove this function. */ function cleanKey(key: string): string { const idx = key.indexOf(":"); if (idx > 0 && key.startsWith("config:", idx + 1)) { return key.substring(0, idx) + ":" + key.substring(idx + 1 + "config:".length); } return key; }