{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-}

-- Derived from AWS service descriptions, licensed under Apache 2.0.

-- |
-- Module      : Amazonka.ResourceGroups.Types.ResourceQuery
-- Copyright   : (c) 2013-2021 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
-- Stability   : auto-generated
-- Portability : non-portable (GHC extensions)
module Amazonka.ResourceGroups.Types.ResourceQuery where

import qualified Amazonka.Core as Core
import qualified Amazonka.Lens as Lens
import qualified Amazonka.Prelude as Prelude
import Amazonka.ResourceGroups.Types.QueryType

-- | The query that is used to define a resource group or a search for
-- resources. A query specifies both a query type and a query string as a
-- JSON object. See the examples section for example JSON strings.
--
-- The examples that follow are shown as standard JSON strings. If you
-- include such a string as a parameter to the AWS CLI or an SDK API, you
-- might need to \'escape\' the string into a single line. For example, see
-- the
-- <https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html Quoting strings>
-- in the /AWS CLI User Guide/.
--
-- __Example 1__
--
-- The following generic example shows a resource query JSON string that
-- includes only resources that meet the following criteria:
--
-- -   The resource type must be either @resource_type1@ or
--     @resource_type2@.
--
-- -   The resource must have a tag @Key1@ with a value of either @ValueA@
--     or @ValueB@.
--
-- -   The resource must have a tag @Key2@ with a value of either @ValueC@
--     or @ValueD@.
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": { \"ResourceTypeFilters\": [ \"resource_type1\", \"resource_type2\"], \"TagFilters\": [ { \"Key\": \"Key1\", \"Values\": [\"ValueA\",\"ValueB\"] }, { \"Key\":\"Key2\", \"Values\":[\"ValueC\",\"ValueD\"] } ] } }@
--
-- This has the equivalent \"shortcut\" syntax of the following:
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": { \"ResourceTypeFilters\": [ \"resource_type1\", \"resource_type2\"], \"TagFilters\": [ { \"Key1\": [\"ValueA\",\"ValueB\"] }, { \"Key2\": [\"ValueC\",\"ValueD\"] } ] } }@
--
-- __Example 2__
--
-- The following example shows a resource query JSON string that includes
-- only Amazon EC2 instances that are tagged @Stage@ with a value of
-- @Test@.
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": \"{ \"ResourceTypeFilters\": \"AWS::EC2::Instance\", \"TagFilters\": { \"Stage\": \"Test\" } } }@
--
-- __Example 3__
--
-- The following example shows a resource query JSON string that includes
-- resource of any supported type as long as it is tagged @Stage@ with a
-- value of @Prod@.
--
-- @{ \"Type\": \"TAG_FILTERS_1_0\", \"Query\": { \"ResourceTypeFilters\": \"AWS::AllSupported\", \"TagFilters\": { \"Stage\": \"Prod\" } } }@
--
-- __Example 4__
--
-- The following example shows a resource query JSON string that includes
-- only Amazon EC2 instances and Amazon S3 buckets that are part of the
-- specified AWS CloudFormation stack.
--
-- @{ \"Type\": \"CLOUDFORMATION_STACK_1_0\", \"Query\": { \"ResourceTypeFilters\": [ \"AWS::EC2::Instance\", \"AWS::S3::Bucket\" ], \"StackIdentifier\": \"arn:aws:cloudformation:us-west-2:123456789012:stack\/AWStestuseraccount\/fb0d5000-aba8-00e8-aa9e-50d5cEXAMPLE\" } }@
--
-- /See:/ 'newResourceQuery' smart constructor.
data ResourceQuery = ResourceQuery'
  { -- | The type of the query. You can use the following values:
    --
    -- -   /@CLOUDFORMATION_STACK_1_0:@/ Specifies that the @Query@ contains an
    --     ARN for a CloudFormation stack.
    --
    -- -   /@TAG_FILTERS_1_0:@/ Specifies that the @Query@ parameter contains a
    --     JSON string that represents a collection of simple tag filters for
    --     resource types and tags. The JSON string uses a syntax similar to
    --     the @ GetResources @ operation, but uses only the
    --     @  ResourceTypeFilters @ and @ TagFilters @ fields. If you specify
    --     more than one tag key, only resources that match all tag keys, and
    --     at least one value of each specified tag key, are returned in your
    --     query. If you specify more than one value for a tag key, a resource
    --     matches the filter if it has a tag key value that matches /any/ of
    --     the specified values.
    --
    --     For example, consider the following sample query for resources that
    --     have two tags, @Stage@ and @Version@, with two values each:
    --
    --     @[{\"Stage\":[\"Test\",\"Deploy\"]},{\"Version\":[\"1\",\"2\"]}]@
    --
    --     The results of this query could include the following.
    --
    --     -   An EC2 instance that has the following two tags:
    --         @{\"Stage\":\"Deploy\"}@, and @{\"Version\":\"2\"}@
    --
    --     -   An S3 bucket that has the following two tags:
    --         @{\"Stage\":\"Test\"}@, and @{\"Version\":\"1\"}@
    --
    --     The query would not include the following items in the results,
    --     however.
    --
    --     -   An EC2 instance that has only the following tag:
    --         @{\"Stage\":\"Deploy\"}@.
    --
    --         The instance does not have __all__ of the tag keys specified in
    --         the filter, so it is excluded from the results.
    --
    --     -   An RDS database that has the following two tags:
    --         @{\"Stage\":\"Archived\"}@ and @{\"Version\":\"4\"}@
    --
    --         The database has all of the tag keys, but none of those keys has
    --         an associated value that matches at least one of the specified
    --         values in the filter.
    ResourceQuery -> QueryType
type' :: QueryType,
    -- | The query that defines a group or a search.
    ResourceQuery -> Text
query :: Prelude.Text
  }
  deriving (ResourceQuery -> ResourceQuery -> Bool
(ResourceQuery -> ResourceQuery -> Bool)
-> (ResourceQuery -> ResourceQuery -> Bool) -> Eq ResourceQuery
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResourceQuery -> ResourceQuery -> Bool
$c/= :: ResourceQuery -> ResourceQuery -> Bool
== :: ResourceQuery -> ResourceQuery -> Bool
$c== :: ResourceQuery -> ResourceQuery -> Bool
Prelude.Eq, ReadPrec [ResourceQuery]
ReadPrec ResourceQuery
Int -> ReadS ResourceQuery
ReadS [ResourceQuery]
(Int -> ReadS ResourceQuery)
-> ReadS [ResourceQuery]
-> ReadPrec ResourceQuery
-> ReadPrec [ResourceQuery]
-> Read ResourceQuery
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ResourceQuery]
$creadListPrec :: ReadPrec [ResourceQuery]
readPrec :: ReadPrec ResourceQuery
$creadPrec :: ReadPrec ResourceQuery
readList :: ReadS [ResourceQuery]
$creadList :: ReadS [ResourceQuery]
readsPrec :: Int -> ReadS ResourceQuery
$creadsPrec :: Int -> ReadS ResourceQuery
Prelude.Read, Int -> ResourceQuery -> ShowS
[ResourceQuery] -> ShowS
ResourceQuery -> String
(Int -> ResourceQuery -> ShowS)
-> (ResourceQuery -> String)
-> ([ResourceQuery] -> ShowS)
-> Show ResourceQuery
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResourceQuery] -> ShowS
$cshowList :: [ResourceQuery] -> ShowS
show :: ResourceQuery -> String
$cshow :: ResourceQuery -> String
showsPrec :: Int -> ResourceQuery -> ShowS
$cshowsPrec :: Int -> ResourceQuery -> ShowS
Prelude.Show, (forall x. ResourceQuery -> Rep ResourceQuery x)
-> (forall x. Rep ResourceQuery x -> ResourceQuery)
-> Generic ResourceQuery
forall x. Rep ResourceQuery x -> ResourceQuery
forall x. ResourceQuery -> Rep ResourceQuery x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ResourceQuery x -> ResourceQuery
$cfrom :: forall x. ResourceQuery -> Rep ResourceQuery x
Prelude.Generic)

-- |
-- Create a value of 'ResourceQuery' with all optional fields omitted.
--
-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
--
-- The following record fields are available, with the corresponding lenses provided
-- for backwards compatibility:
--
-- 'type'', 'resourceQuery_type' - The type of the query. You can use the following values:
--
-- -   /@CLOUDFORMATION_STACK_1_0:@/ Specifies that the @Query@ contains an
--     ARN for a CloudFormation stack.
--
-- -   /@TAG_FILTERS_1_0:@/ Specifies that the @Query@ parameter contains a
--     JSON string that represents a collection of simple tag filters for
--     resource types and tags. The JSON string uses a syntax similar to
--     the @ GetResources @ operation, but uses only the
--     @  ResourceTypeFilters @ and @ TagFilters @ fields. If you specify
--     more than one tag key, only resources that match all tag keys, and
--     at least one value of each specified tag key, are returned in your
--     query. If you specify more than one value for a tag key, a resource
--     matches the filter if it has a tag key value that matches /any/ of
--     the specified values.
--
--     For example, consider the following sample query for resources that
--     have two tags, @Stage@ and @Version@, with two values each:
--
--     @[{\"Stage\":[\"Test\",\"Deploy\"]},{\"Version\":[\"1\",\"2\"]}]@
--
--     The results of this query could include the following.
--
--     -   An EC2 instance that has the following two tags:
--         @{\"Stage\":\"Deploy\"}@, and @{\"Version\":\"2\"}@
--
--     -   An S3 bucket that has the following two tags:
--         @{\"Stage\":\"Test\"}@, and @{\"Version\":\"1\"}@
--
--     The query would not include the following items in the results,
--     however.
--
--     -   An EC2 instance that has only the following tag:
--         @{\"Stage\":\"Deploy\"}@.
--
--         The instance does not have __all__ of the tag keys specified in
--         the filter, so it is excluded from the results.
--
--     -   An RDS database that has the following two tags:
--         @{\"Stage\":\"Archived\"}@ and @{\"Version\":\"4\"}@
--
--         The database has all of the tag keys, but none of those keys has
--         an associated value that matches at least one of the specified
--         values in the filter.
--
-- 'query', 'resourceQuery_searchQuery' - The query that defines a group or a search.
newResourceQuery ::
  -- | 'type''
  QueryType ->
  -- | 'query'
  Prelude.Text ->
  ResourceQuery
newResourceQuery :: QueryType -> Text -> ResourceQuery
newResourceQuery QueryType
pType_ Text
pSearchQuery_ =
  ResourceQuery' :: QueryType -> Text -> ResourceQuery
ResourceQuery'
    { $sel:type':ResourceQuery' :: QueryType
type' = QueryType
pType_,
      $sel:query:ResourceQuery' :: Text
query = Text
pSearchQuery_
    }

-- | The type of the query. You can use the following values:
--
-- -   /@CLOUDFORMATION_STACK_1_0:@/ Specifies that the @Query@ contains an
--     ARN for a CloudFormation stack.
--
-- -   /@TAG_FILTERS_1_0:@/ Specifies that the @Query@ parameter contains a
--     JSON string that represents a collection of simple tag filters for
--     resource types and tags. The JSON string uses a syntax similar to
--     the @ GetResources @ operation, but uses only the
--     @  ResourceTypeFilters @ and @ TagFilters @ fields. If you specify
--     more than one tag key, only resources that match all tag keys, and
--     at least one value of each specified tag key, are returned in your
--     query. If you specify more than one value for a tag key, a resource
--     matches the filter if it has a tag key value that matches /any/ of
--     the specified values.
--
--     For example, consider the following sample query for resources that
--     have two tags, @Stage@ and @Version@, with two values each:
--
--     @[{\"Stage\":[\"Test\",\"Deploy\"]},{\"Version\":[\"1\",\"2\"]}]@
--
--     The results of this query could include the following.
--
--     -   An EC2 instance that has the following two tags:
--         @{\"Stage\":\"Deploy\"}@, and @{\"Version\":\"2\"}@
--
--     -   An S3 bucket that has the following two tags:
--         @{\"Stage\":\"Test\"}@, and @{\"Version\":\"1\"}@
--
--     The query would not include the following items in the results,
--     however.
--
--     -   An EC2 instance that has only the following tag:
--         @{\"Stage\":\"Deploy\"}@.
--
--         The instance does not have __all__ of the tag keys specified in
--         the filter, so it is excluded from the results.
--
--     -   An RDS database that has the following two tags:
--         @{\"Stage\":\"Archived\"}@ and @{\"Version\":\"4\"}@
--
--         The database has all of the tag keys, but none of those keys has
--         an associated value that matches at least one of the specified
--         values in the filter.
resourceQuery_type :: Lens.Lens' ResourceQuery QueryType
resourceQuery_type :: (QueryType -> f QueryType) -> ResourceQuery -> f ResourceQuery
resourceQuery_type = (ResourceQuery -> QueryType)
-> (ResourceQuery -> QueryType -> ResourceQuery)
-> Lens ResourceQuery ResourceQuery QueryType QueryType
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\ResourceQuery' {QueryType
type' :: QueryType
$sel:type':ResourceQuery' :: ResourceQuery -> QueryType
type'} -> QueryType
type') (\s :: ResourceQuery
s@ResourceQuery' {} QueryType
a -> ResourceQuery
s {$sel:type':ResourceQuery' :: QueryType
type' = QueryType
a} :: ResourceQuery)

-- | The query that defines a group or a search.
resourceQuery_searchQuery :: Lens.Lens' ResourceQuery Prelude.Text
resourceQuery_searchQuery :: (Text -> f Text) -> ResourceQuery -> f ResourceQuery
resourceQuery_searchQuery = (ResourceQuery -> Text)
-> (ResourceQuery -> Text -> ResourceQuery)
-> Lens ResourceQuery ResourceQuery Text Text
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\ResourceQuery' {Text
query :: Text
$sel:query:ResourceQuery' :: ResourceQuery -> Text
query} -> Text
query) (\s :: ResourceQuery
s@ResourceQuery' {} Text
a -> ResourceQuery
s {$sel:query:ResourceQuery' :: Text
query = Text
a} :: ResourceQuery)

instance Core.FromJSON ResourceQuery where
  parseJSON :: Value -> Parser ResourceQuery
parseJSON =
    String
-> (Object -> Parser ResourceQuery)
-> Value
-> Parser ResourceQuery
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Core.withObject
      String
"ResourceQuery"
      ( \Object
x ->
          QueryType -> Text -> ResourceQuery
ResourceQuery'
            (QueryType -> Text -> ResourceQuery)
-> Parser QueryType -> Parser (Text -> ResourceQuery)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> (Object
x Object -> Text -> Parser QueryType
forall a. FromJSON a => Object -> Text -> Parser a
Core..: Text
"Type") Parser (Text -> ResourceQuery)
-> Parser Text -> Parser ResourceQuery
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (Object
x Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
Core..: Text
"Query")
      )

instance Prelude.Hashable ResourceQuery

instance Prelude.NFData ResourceQuery

instance Core.ToJSON ResourceQuery where
  toJSON :: ResourceQuery -> Value
toJSON ResourceQuery' {Text
QueryType
query :: Text
type' :: QueryType
$sel:query:ResourceQuery' :: ResourceQuery -> Text
$sel:type':ResourceQuery' :: ResourceQuery -> QueryType
..} =
    [Pair] -> Value
Core.object
      ( [Maybe Pair] -> [Pair]
forall a. [Maybe a] -> [a]
Prelude.catMaybes
          [ Pair -> Maybe Pair
forall a. a -> Maybe a
Prelude.Just (Text
"Type" Text -> QueryType -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
Core..= QueryType
type'),
            Pair -> Maybe Pair
forall a. a -> Maybe a
Prelude.Just (Text
"Query" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
Core..= Text
query)
          ]
      )