NewRelicPS.GraphQLQueries.psm1

# Gets the GraphQL query to retrieve NRQL conditions
Function Get-GraphQLQueryGetNRQLCondition {
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [string] $NextCursor,
    [string] $SearchCriteria
  )
  Return "{
    actor {
      account(id: $AccountId) {
        alerts {
          nrqlConditionsSearch ( cursor: `"$NextCursor`", searchCriteria: {
            $SearchCriteria
          })
          {
            nextCursor nrqlConditions {
              ...on AlertsNrqlStaticCondition {
                valueFunction
              }
              ...on AlertsNrqlBaselineCondition {
                baselineDirection
              }
              ...on AlertsNrqlOutlierCondition {
                expectedGroups
              }
              description
              enabled
              expiration {
                closeViolationsOnExpiration
                expirationDuration
                openViolationOnExpiration
              }
              id
              name
              nrql {
                query
                evaluationOffset
              }
              policyId
              runbookUrl
              terms {
                operator
                priority
                threshold
                thresholdDuration
                thresholdOccurrences
              }
              type
              violationTimeLimit
            }
            totalCount
          }
        }
      }
    }
  }"

}

# Gets the GraphQL query to create NRQL Baseline condition
Function Get-GraphQLQueryCreateNRQLCondition {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [string] $Name,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [string] $PolicyId,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [pscustomobject] $Terms,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [string] $Query,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [ValidateSet ('alertsNrqlConditionBaselineCreate', 'alertsNrqlConditionOutlierCreate', 'alertsNrqlConditionStaticCreate')]
    [string] $QueryType,

    # Expiration Optional Parameters
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [boolean] $CloseViolationsOnExpiration = $false,
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [string] $ExpirationDuration = '600',
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [boolean] $OpenViolationOnExpiration = $true,

    # Other Optional Parameters
    [ValidateSet ('UPPER_ONLY', 'LOWER_ONLY', 'UPPER_AND_LOWER')]
    [string] $BaselineDirection = 'UPPER_ONLY',
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [string]$Description = '',
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [boolean] $Enabled = $true,
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [int] $ExpectedGroups = 1,
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [int] $EvaluationOffset = '3',
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    $OpenViolationOnGroupOverlap = $true,
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [string] $RunbookURL = '',
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [ValidateSet ('SINGLE_VALUE', 'SUM')]
    [string] $ValueFunction = 'SINGLE_VALUE',
    [Parameter (ValueFromPipelineByPropertyName = $true)]
    [ValidateSet ('ONE_HOUR', 'TWO_HOURS', 'FOUR_HOURS', 'EIGHT_HOURS', 'TWELVE_HOURS', 'TWENTY_FOUR_HOURS')]
    [string] $ViolationTimeLimit = 'TWENTY_FOUR_HOURS'

  )
  Process {
    # Each type of NRQL condition may have specific fields and return values
    Switch ($QueryType) {
      'alertsNrqlConditionBaselineCreate' {
        $typeSpecificItems = @{
          baselineDirection = $BaselineDirection
          expiration        = "{closeViolationsOnExpiration: $("$CloseViolationsOnExpiration".ToLower()) expirationDuration: $ExpirationDuration openViolationOnExpiration: $("$OpenViolationOnExpiration".ToLower()) }"
        }
        $typeSpecificReturns = @(
          'baselineDirection',
          'expiration { closeViolationsOnExpiration expirationDuration openViolationOnExpiration }'
        )
      }
      'alertsNrqlConditionOutlierCreate' {
        $typeSpecificItems = @{
          expectedGroups              = $ExpectedGroups
          openViolationOnGroupOverlap = $OpenViolationOnGroupOverlap.ToString().ToLower()
        }
        $typeSpecificReturns = @(
          'expectedGroups',
          'openViolationOnGroupOverlap'
        )
      }
      'alertsNrqlConditionStaticCreate' {
        $typeSpecificItems = @{
          valueFunction = $ValueFunction.ToUpper()
          expiration    = "{closeViolationsOnExpiration: $("$CloseViolationsOnExpiration".ToLower()) expirationDuration: $ExpirationDuration openViolationOnExpiration: $("$OpenViolationOnExpiration".ToLower()) }"
        }
        $typeSpecificReturns = @(
          'valueFunction',
          'expiration { closeViolationsOnExpiration expirationDuration openViolationOnExpiration }'
        )
      }
    }

    Foreach ($key in $typeSpecificItems.keys) {
      $typeSpecificString += "$key`: $($typeSpecificItems[$key])`n "
    }

    Return " mutation {
      $QueryType(
        accountId: $AccountId,
        policyId: $PolicyId,
        condition: {
          name: `"$Name`"
          description: `"$Description`"
          enabled: $("$Enabled".ToLower())
          $typeSpecificString
          nrql: { query: `"$Query`" evaluationOffset: $EvaluationOffset }
          runbookUrl: `"$RunbookURL`"
          terms: $Terms
          violationTimeLimit: $ViolationTimeLimit
        })
        {
          $($typeSpecificReturns -join ("`n "))
          description
          enabled
          id
          name
          nrql { query evaluationOffset }
          policyId
          runbookUrl
          terms { operator priority threshold thresholdDuration thresholdOccurrences }
          type
          violationTimeLimit
        }
      }"

  }
}

Function Get-GraphQLQueryUpdateNRQLCondition {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [string] $ConditionId,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [string] $FieldsToUpdate,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [ValidateSet('alertsNrqlConditionBaselineUpdate', 'alertsNrqlConditionOutlierUpdate', 'alertsNrqlConditionStaticUpdate')]
    [string] $QueryType
  )
  Process {
    Switch ($QueryType) {
      'alertsNrqlConditionBaselineUpdate' { $lineFragment = '...on AlertsNrqlBaselineCondition { baselineDirection }' }
      'alertsNrqlConditionOutlierUpdate' { $lineFragment = '...on AlertsNrqlOutlierCondition { expectedGroups }' }
      'alertsNrqlConditionStaticUpdate' { $lineFragment = '...on AlertsNrqlStaticCondition { valueFunction }' }
    }
    Return " mutation {
      $QueryType(
        id: $ConditionId,
        accountId: $AccountId,
        condition: {
          $FieldsToUpdate
        })
      {
        $lineFragment
        description
        enabled
        expiration {
          closeViolationsOnExpiration
          expirationDuration
          openViolationOnExpiration
        }
        id
        name
        nrql {
          query
          evaluationOffset
        }
        policyId
        runbookUrl
        terms {
          operator
          priority
          threshold
          thresholdDuration
          thresholdOccurrences
        }
        type
        violationTimeLimit
      }
    }"

  }
}

Function Get-GraphQLQueryDeleteCondition {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [string] $ConditionId
  )
  Process {
    Return " mutation {
      alertsConditionDelete(
        accountId:$AccountId,
        id: $ConditionId
      )
      {
        id
      }
    }"

  }
}

# https://docs.newrelic.com/docs/apis/nerdgraph/examples/export-import-dashboards-using-api/
Function Get-GraphQLQueryGetDashboard {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
    [string] $DashboardId
  )
  Process {
    Return "
    {
      actor {
        entity(guid: `"$DashboardId`") {
          ... on DashboardEntity {
            name
            permissions
            pages {
              guid
              name
              widgets {
                linkedEntities { guid }
                visualization { id }
                title
                layout { row width height column }
                rawConfiguration
              }
            }
            variables {
              isMultiSelection
              name
              replacementStrategy
              title
              type
              defaultValues {
                value {
                  string
                }
              }
              options {
                ignoreTimeRange
              }
              nrqlQuery {
                query
                accountIds
              }
              items {
                title
                value
              }
            }
          }
        }
      }
    }"

  }
}

Function Get-GraphQLQueryGetDashboardList {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter ()]
    [string] $NameFilter,
    [Parameter ()]
    [string] $NextCursor
  )
  Process {
    If ($NextCursor) {
      $cursorString = "(cursor: `"$NextCursor`")"
    }

    Return "
    {
      actor {
        entitySearch(queryBuilder: {type: DASHBOARD, name: `"$NameFilter`"}) {
          results $cursorString{
            nextCursor
            entities {
              ... on DashboardEntityOutline {
                guid
                name
                accountId
              }
            }
          }
        }
      }
    }"

  }
}

Function Get-GraphQLQueryCreateDashboard {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId
  )
  Process {
    Return "
    mutation create(`$dashboard: DashboardInput!) {
      dashboardCreate(accountId: $AccountId, dashboard: `$dashboard) {
        entityResult {
          guid
          name
        }
        errors {
          description
        }
      }
    }"

  }
}

Function Get-GraphQLQueryUpdateDashboard {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $DashboardId
  )
  Process {
    Return "
    mutation create(`$dashboard: DashboardInput!) {
      dashboardUpdate(dashboard: `$dashboard, guid: `"$DashboardId`") {
        entityResult {
          guid
          name
        }
        errors {
          description
          type
        }
      }
    }"

  }
}

Function Get-GraphQLQueryDeleteDashboard {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $DashboardId
  )
  Process {
    Return "
    mutation {
      dashboardDelete(guid: `"$DashboardId`") {
        status
      }
    }"

  }
}

Function Get-GraphQLQueryUndeleteDashboard {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $DashboardId
  )
  Process {
    Return "
    mutation {
      dashboardUndelete(guid: `"$DashboardId`") {
        errors {
          description
          type
        }
      }
    }"

  }
}

Function Get-GraphQLQueryNRQLQuery {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true)]
    [string] $Query
  )
  Process {
    Return "{
      actor {
        account(id: $AccountId) {
          id
          nrql(query: `"$Query`"`) {
            results
          }
        }
      }
    }"

  }
}

Function Get-GraphQLQueryAddTagToEntity {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $EntityGUID,
    [Parameter (Mandatory = $true)]
    [string] $TagKey,
    [Parameter (Mandatory = $true)]
    [string] $TagValue
  )
  Process {
    Return "mutation {
      taggingAddTagsToEntity(guid: `"$EntityGUID`"`, tags: {key: `"$TagKey`"`, values: [`"$TagValue`"`]}) {
        errors {
          message
        }
      }
    }"

  }
}
Function Get-GraphQLQueryCreateMutingRuleBySchedule {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true)]
    [string] $RuleName,
    [Parameter (Mandatory = $true)]
    [string] $TagKey,
    [Parameter (Mandatory = $true)]
    [string] $TagValue,
    [Parameter (Mandatory = $true)]
    [string] $StartTime,
    [Parameter (Mandatory = $true)]
    [string] $EndTime,
    [Parameter (Mandatory = $true)]
    [string] $TimeZone,
    [string] $RuleDescription
  )
  Process {
    Return "mutation {
          alertsMutingRuleCreate(accountId: $AccountId, rule: {
            name: `"$RuleName`"`,
            description: `"$RuleDescription`"`,
            enabled: true,
            condition: {
              operator: AND,
              conditions: [{
                attribute: `"tags.$TagKey`"`,
                operator: EQUALS,
                values: [`"$TagValue`"`]
              }]
            }
            schedule: {
              startTime: `"$StartTime`"`,
              endTime: `"$EndTime`"`,
              timeZone: `"$TimeZone`"`,
              }
          }) {
            id
          }
        }"

  }
}

Function Get-GraphQLQueryGetMetricNormalizationRule {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true)]
    [string] $RuleId
  )
  Return "{
    actor {
      account(id: $AccountId) {
        metricNormalization {
          metricNormalizationRule(id: $RuleId) {
            action
            applicationGuid
            applicationName
            createdAt
            enabled
            evalOrder
            id
            matchExpression
            notes
            replacement
            terminateChain
          }
        }
      }
    }
  }"

}

Function Get-GraphQLQueryGetMetricNormalizationRuleList {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId
  )
  Return "{
    actor {
      account(id: $AccountId) {
        metricNormalization {
          metricNormalizationRules {
            id
            applicationName
            createdAt
            enabled
            evalOrder
            matchExpression
            notes
            replacement
            terminateChain
            applicationGuid
            action
          }
        }
      }
    }
  }"

}
Function Get-GraphQLQueryCreateNormalizationRule {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true)]
    [string] $Action,
    [Parameter (Mandatory = $true)]
    [string] $ApplicationGUID,
    [Parameter (Mandatory = $true)]
    [string] $Expression,
    [boolean] $Enabled = $true,
    [string] $Notes = '',
    [string] $Order=9000,
    [string] $ReplacementExpression = '',
    [boolean] $TerminateChain = $true
  )
  Return "mutation {
    metricNormalizationCreateRule(accountId: $AccountId, rule: {
      evalOrder: $Order,
      action: $Action,
      applicationGuid: `"$ApplicationGUID`",
      enabled: $("$Enabled".ToLower()),
      matchExpression: `"$Expression`",
      notes: `"$Notes`",
      replacement: `"$ReplacementExpression`",
      terminateChain: $("$TerminateChain".ToLower())})
      {
        rule {
          id
        }
      }
    }"

}

Function Get-GraphQLQueryUpdateNormalizationRule {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true)]
    [string] $RuleId,
    [Parameter (Mandatory = $true)]
    [string] $Action,
    [Parameter (Mandatory = $true)]
    [string] $Expression,
    [Parameter (Mandatory = $true)]
    [boolean] $Enabled,
    [string] $Notes,
    [string] $Order,
    [string] $ReplacementExpression,
    [nullable[boolean]] $TerminateChain
  )
  $ruleProperties = "id: $RuleId, action: $Action, enabled: $("$Enabled".ToLower()), matchExpression: $Expression"

  Switch ($true) {
    {$Order} {$ruleProperties += ", evalOrder: $Order"}
    {$Notes} {$ruleProperties += ", notes: `"$Notes`""}
    {$ReplacementExpression} {$ruleProperties += ", replacement: `"$ReplacementExpression`""}
    {$null -ne $TerminateChain} {$ruleProperties += ", terminateChain: $("$TerminateChain".ToLower())"}
  }

  Return "mutation {
    metricNormalizationEditRule(
    accountId: $AccountId,
    rule: {
      $ruleProperties
    })
    {
      rule {
        action
        applicationGuid
        applicationName
        createdAt
        enabled
        evalOrder
        id
        matchExpression
        notes
        replacement
        terminateChain
      }
    }
  }"

}
Function Get-GraphQLQueryGetAPMApplicationEntityGUID {
  [CMDLetBinding()]
  [OutputType([string])]
  Param (
    [Parameter (Mandatory = $true)]
    [string] $AccountId,
    [Parameter (Mandatory = $true)]
    [string] $Type,
    [Parameter (Mandatory = $true)]
    [string] $Name,
    [string] $NextCursor

  )
  If ($NextCursor) {
    $cursorString = "(cursor: `"$NextCursor`")"
  }

  Return "{
    actor {
      entitySearch(queryBuilder: {tags: {key: `"accountId`", value: `"$AccountId`"}, type: $Type, name: $Name}) {
        results $cursorString {
          entities {
            guid
            name
            alertSeverity
            domain
            entityType
            indexedAt
            permalink
            reporting
            type
            account {
              id
              name
            }
            tags {
              key
              values
            }
          }
          nextCursor
        }
      }
    }
  }"

}