import { DefinitionResourceReference } from "azure-devops-node-api/interfaces/BuildInterfaces" ; import { AzureKeyVaultVariableGroupProviderData , VariableGroup , VariableGroupParameters , } from "azure-devops-node-api/interfaces/TaskAgentInterfaces" ; import { Config } from "../../config" ; import { logger } from "../../logger" ; import { VariableGroupData , VariableGroupDataVariable } from "../../types" ; import { getBuildApi , getTaskAgentApi } from "../azdoClient" ; import { AzureDevOpsOpts } from "../git" ; import { createServiceEndpointIfNotExists } from "./serviceEndpoint" ; import { build as buildError } from "../errorBuilder" ; import { errorStatusCode } from "../errorStatusCode" ; param variableGroup returns export const buildVariablesMap = ( variables ) : VariableGroupDataVariable => { const variablesMap = { } ; logger . debug ( `variables: ${ JSON . stringify ( variables ) }` ) ; for ( const [ key , value ] of Object . entries ( variables ) ) { logger . debug ( `variable: ${ key }: value: ${ JSON . stringify ( value ) }` ) ; variablesMap [ key ] = value ; } logger . debug ( `variablesMap: ${ JSON . stringify ( variablesMap ) }` ) ; return variablesMap ; } ; param variableGroup param opts returns export const authorizeAccessToAllPipelines = async ( variableGroup , opts = { } ) : Promise < boolean > => { const message = `Resource definition for all pipelines to access Variable Group ${ variableGroup . name }` ; if ( ! variableGroup . id ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , "var-group-authorize-all-pipelines-err-missing-id" ) ; } try { logger . info ( `Creating ${ message }` ) ; const config = Config ( ) ; const { project = config . azure_devops && config . azure_devops . project , } = opts ; const resourceDefinition = { authorized : true , id : variableGroup . id . toString ( ) , name : variableGroup . name , type : "variablegroup" , } ; logger . debug ( `Creating resource definition: ${ JSON . stringify ( resourceDefinition ) }` ) ; const buildClient = await getBuildApi ( opts ) ; const resourceDefinitionResponse = await buildClient . authorizeProjectResources ( [ resourceDefinition ] , project ! ) ; logger . debug ( `Created resource definition: ${ JSON . stringify ( resourceDefinitionResponse ) }` ) ; logger . info ( `Authorized access ${ message } authorized flag set to ${ resourceDefinitionResponse [ 0 ] . authorized }` ) ; return true ; } catch ( err ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , { errorKey : "var-group-authorize-all-pipelines-err" , values : [ variableGroup . name || "" ] , } , err ) ; } } ; param variableGroupData param accessToAllPipelines param opts returns export const doAddVariableGroup = async ( variableGroupData , accessToAllPipelines , opts = { } ) : Promise < VariableGroup > => { const message = `Variable Group ${ variableGroupData . name }` ; const config = Config ( ) ; const { project = config . azure_devops && config . azure_devops . project } = opts ; if ( typeof project !== "string" ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , "var-group-add-err-project-missing" ) ; } logger . debug ( `Creating new Variable Group ${ JSON . stringify ( variableGroupData ) }` ) ; logger . info ( `Attempting to create Variable Group in project '${ project }'` ) ; const taskClient = await getTaskAgentApi ( opts ) ; const group = await taskClient . addVariableGroup ( variableGroupData , project ) ; logger . debug ( `Created new Variable Group: ${ JSON . stringify ( group ) }` ) ; logger . info ( `Created ${ message } with id: ${ group . id }` ) ; if ( accessToAllPipelines ) { await authorizeAccessToAllPipelines ( group , opts ) ; } return group ; } ; param variableGroupData param opts returns export const addVariableGroup = async ( variableGroupData , opts = { } ) : Promise < VariableGroup > => { const message = `Variable Group ${ variableGroupData . name }` ; logger . info ( `Creating ${ message }` ) ; if ( ! variableGroupData . variables ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , "var-group-add-err-vars-missing" ) ; } try { const variablesMap = buildVariablesMap ( variableGroupData . variables ) ; const params = { description : variableGroupData . description , name : variableGroupData . name , type : "Vsts" , variables : variablesMap , } ; return doAddVariableGroup ( params , true , opts ) ; } catch ( err ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , { errorKey : "var-group-add-err" , values : [ variableGroupData . name || "" ] , } , err ) ; } } ; param variableGroupData param opts returns export const addVariableGroupWithKeyVaultMap = async ( variableGroupData , opts = { } ) : Promise < VariableGroup > => { const message = `Variable Group ${ variableGroupData . name }` ; try { logger . info ( `Creating ${ message }` ) ; if ( variableGroupData . key_vault_provider === undefined || variableGroupData . key_vault_provider === null || variableGroupData . key_vault_provider . service_endpoint === undefined || typeof variableGroupData . key_vault_provider . service_endpoint === null ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , "var-group-add-with-key-vault-err-missing-provider" ) ; } logger . info ( `Checking for Service endpoint` ) ; const serviceEndpoint = await createServiceEndpointIfNotExists ( variableGroupData . key_vault_provider . service_endpoint , opts ) ; logger . info ( `Using Service endpoint id: ${ serviceEndpoint . id } for Key Vault` ) ; const kvProvideData = { serviceEndpointId : serviceEndpoint . id , vault : variableGroupData . key_vault_provider . name , } ; const secretsMap = buildVariablesMap ( variableGroupData . variables ) ; const params = { description : variableGroupData . description , name : variableGroupData . name , providerData : kvProvideData , type : "AzureKeyVault" , variables : secretsMap , } ; return doAddVariableGroup ( params , true , opts ) ; } catch ( err ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , { errorKey : "var-group-add-with-key-vault-err" , values : [ variableGroupData . name || "" ] , } , err ) ; } } ; param opts param name returns export const deleteVariableGroup = async ( opts , name ) : Promise < boolean > => { try { const taskClient = await getTaskAgentApi ( opts ) ; const project = opts . project ! ; const groups = await taskClient . getVariableGroups ( project , name ) ; if ( groups ?. [ 0 ] ?. id ) { await taskClient . deleteVariableGroup ( project , groups [ 0 ] . id ) ; return true ; } return false ; } catch ( err ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , { errorKey : "var-group-delete-var-group-err" , values : [ opts . project ! , name ] , } , err ) ; } } ; param opts param name returns export const hasVariableGroup = async ( opts , name ) : Promise < boolean > => { try { const taskClient = await getTaskAgentApi ( opts ) ; const project = opts . project ! ; const groups = await taskClient . getVariableGroups ( project , name ) ; return groups ?. [ 0 ] ?. name === name ; } catch ( err ) { throw buildError ( errorStatusCode . AZURE_VARIABLE_GROUP_ERR , { errorKey : "var-group-has-var-group-err" , values : [ opts . project ! , name ] , } , err ) ; } } ;