using System; using System.Collections.Generic; using System.Linq; using GitHub.Services.WebApi; namespace GitHub.DistributedTask.WebApi { /// /// Utility class to perform operations on Variable groups. /// public static class VariableGroupUtility { public static VariableValue Clone(this VariableValue value) { if (keyVaultVariableType == value.GetType()) { return new AzureKeyVaultVariableValue((AzureKeyVaultVariableValue)value); } return new VariableValue(value); } public static void PopulateVariablesAndProviderData(this VariableGroup group, String variablesJson, String providerDataJson) { switch (group.Type) { case VariableGroupType.Vsts: if (variablesJson != null) { group.Variables = JsonUtility.FromString>(variablesJson); } if (providerDataJson != null) { group.ProviderData = JsonUtility.FromString(providerDataJson); } break; case VariableGroupType.AzureKeyVault: if (variablesJson != null) { var azureKeyVaultVariableValues = JsonUtility.FromString>(variablesJson); if (azureKeyVaultVariableValues != null) { foreach (var azureKeyVaultVariableValue in azureKeyVaultVariableValues) { group.Variables[azureKeyVaultVariableValue.Key] = azureKeyVaultVariableValue.Value; } } } if (providerDataJson != null) { group.ProviderData = JsonUtility.FromString(providerDataJson); } break; } } public static void PopulateVariablesAndProviderData(this VariableGroupParameters variableGroupParameters, String variablesJson, String providerDataJson) { switch (variableGroupParameters.Type) { case VariableGroupType.Vsts: if (variablesJson != null) { variableGroupParameters.Variables = JsonUtility.FromString>(variablesJson); } if (providerDataJson != null) { variableGroupParameters.ProviderData = JsonUtility.FromString(providerDataJson); } break; case VariableGroupType.AzureKeyVault: if (variablesJson != null) { var azureKeyVaultVariableValues = JsonUtility.FromString>(variablesJson); if (azureKeyVaultVariableValues != null) { foreach (var azureKeyVaultVariableValue in azureKeyVaultVariableValues) { variableGroupParameters.Variables[azureKeyVaultVariableValue.Key] = azureKeyVaultVariableValue.Value; } } } if (providerDataJson != null) { variableGroupParameters.ProviderData = JsonUtility.FromString(providerDataJson); } break; } } /// /// Get list of cloned variable groups /// /// /// public static IList CloneVariableGroups(IList source) { var clonedVariableGroups = new List(); if (source == null) { return clonedVariableGroups; } foreach (var group in source) { if (group != null) { clonedVariableGroups.Add(group.Clone()); } } return clonedVariableGroups; } /// /// Replace secret values in group variables with null /// /// Variable groups to be cleared for secret variables /// List of cleared variable groups public static IList ClearSecrets(IList variableGroups) { var groups = new List(); if (variableGroups == null) { return groups; } foreach (var group in variableGroups) { if (group != null) { var clearedGroup = group.Clone(); // Replacing secret variable's value with null foreach (var variable in clearedGroup.Variables) { if (variable.Value != null && variable.Value.IsSecret) { variable.Value.Value = null; } } groups.Add(clearedGroup); } } return groups; } /// /// Replace all secrets in variables with null /// /// Variable set /// Dictionary of variables public static IDictionary ClearSecrets(IDictionary variables) { var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); if (variables == null) { return dictionary; } foreach (var kvp in variables) { if (kvp.Value != null) { var clonedValue = kvp.Value.Clone(); if (kvp.Value.IsSecret) { clonedValue.Value = null; } dictionary[kvp.Key] = clonedValue; } } return dictionary; } /// /// Check if any variable group has variable with secret value /// /// Variable groups to check if contains any secret variable with value. /// Result public static bool HasSecretWithValue(IList variableGroups) { if (variableGroups == null || variableGroups.Count == 0) { return false; } foreach (var group in variableGroups) { if (group != null && HasSecretWithValue(group.Variables)) { return true; } } return false; } /// /// Check if Variables has any secret value /// /// Variable set to check for any secret value /// public static bool HasSecretWithValue(IDictionary variables) { if (variables == null || variables.Count == 0) { return false; } return variables.Any(s => s.Value != null && s.Value.IsSecret && !String.IsNullOrEmpty(s.Value.Value)); } /// /// Check if any secret variable exists in variable group /// /// Variable groups to check if contains any secret variable /// Result public static bool HasSecret(IList variableGroups) { if (variableGroups == null || variableGroups.Count == 0) { return false; } foreach (var group in variableGroups) { if (group != null && HasSecret(group.Variables)) { return true; } } return false; } /// /// Check if variable set contains any secret variable /// /// Variable set to be checked for secret variable /// public static bool HasSecret(IDictionary variables) { if (variables != null) { return variables.Any(v => v.Value != null && v.Value.IsSecret); } return false; } /// /// Copies secrets from source variable groups to target variable groups /// /// Source variable groups /// Target variable groups /// public static void FillSecrets( IList sourceGroups, IList targetGroups) { if (sourceGroups == null || sourceGroups.Count == 0) { return; } if (targetGroups == null) { throw new ArgumentNullException("targetGroups"); } foreach (var sourceGroup in sourceGroups) { var targetGroup = targetGroups.FirstOrDefault(group => group.Id == sourceGroup.Id); if (targetGroup != null) { if (sourceGroup.Variables == null || sourceGroup.Variables.Count == 0) { // nothing to fill continue; } if (targetGroup.Variables == null) { throw new ArgumentNullException(nameof(targetGroup.Variables)); } foreach (var variable in sourceGroup.Variables.Where(x => x.Value.IsSecret)) { targetGroup.Variables[variable.Key] = variable.Value.Clone(); } } } } private static Type keyVaultVariableType = typeof(AzureKeyVaultVariableValue); } }