diff --git a/client/client.go b/client/client.go index eebc29b35..24c81b55f 100644 --- a/client/client.go +++ b/client/client.go @@ -17,6 +17,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/apigateway" "github.com/aws/aws-sdk-go-v2/service/apigatewayv2" "github.com/aws/aws-sdk-go-v2/service/applicationautoscaling" + "github.com/aws/aws-sdk-go-v2/service/appsync" "github.com/aws/aws-sdk-go-v2/service/athena" "github.com/aws/aws-sdk-go-v2/service/autoscaling" "github.com/aws/aws-sdk-go-v2/service/backup" @@ -123,6 +124,7 @@ type Services struct { Apigateway ApigatewayClient Apigatewayv2 Apigatewayv2Client ApplicationAutoscaling ApplicationAutoscalingClient + AppSync AppSyncClient Athena AthenaClient Autoscaling AutoscalingClient Backup BackupClient @@ -621,6 +623,7 @@ func initServices(region string, c aws.Config) Services { Apigateway: apigateway.NewFromConfig(awsCfg), Apigatewayv2: apigatewayv2.NewFromConfig(awsCfg), ApplicationAutoscaling: applicationautoscaling.NewFromConfig(awsCfg), + AppSync: appsync.NewFromConfig(awsCfg), Athena: athena.NewFromConfig(awsCfg), Autoscaling: autoscaling.NewFromConfig(awsCfg), Backup: backup.NewFromConfig(awsCfg), diff --git a/client/mocks/mock_appsync.go b/client/mocks/mock_appsync.go new file mode 100644 index 000000000..c093ee2d6 --- /dev/null +++ b/client/mocks/mock_appsync.go @@ -0,0 +1,56 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/cloudquery/cq-provider-aws/client (interfaces: AppSyncClient) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + appsync "github.com/aws/aws-sdk-go-v2/service/appsync" + gomock "github.com/golang/mock/gomock" +) + +// MockAppSyncClient is a mock of AppSyncClient interface. +type MockAppSyncClient struct { + ctrl *gomock.Controller + recorder *MockAppSyncClientMockRecorder +} + +// MockAppSyncClientMockRecorder is the mock recorder for MockAppSyncClient. +type MockAppSyncClientMockRecorder struct { + mock *MockAppSyncClient +} + +// NewMockAppSyncClient creates a new mock instance. +func NewMockAppSyncClient(ctrl *gomock.Controller) *MockAppSyncClient { + mock := &MockAppSyncClient{ctrl: ctrl} + mock.recorder = &MockAppSyncClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAppSyncClient) EXPECT() *MockAppSyncClientMockRecorder { + return m.recorder +} + +// ListGraphqlApis mocks base method. +func (m *MockAppSyncClient) ListGraphqlApis(arg0 context.Context, arg1 *appsync.ListGraphqlApisInput, arg2 ...func(*appsync.Options)) (*appsync.ListGraphqlApisOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ListGraphqlApis", varargs...) + ret0, _ := ret[0].(*appsync.ListGraphqlApisOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListGraphqlApis indicates an expected call of ListGraphqlApis. +func (mr *MockAppSyncClientMockRecorder) ListGraphqlApis(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListGraphqlApis", reflect.TypeOf((*MockAppSyncClient)(nil).ListGraphqlApis), varargs...) +} diff --git a/client/services.go b/client/services.go index 8fae1d589..e27916afd 100644 --- a/client/services.go +++ b/client/services.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/apigateway" "github.com/aws/aws-sdk-go-v2/service/apigatewayv2" "github.com/aws/aws-sdk-go-v2/service/applicationautoscaling" + "github.com/aws/aws-sdk-go-v2/service/appsync" "github.com/aws/aws-sdk-go-v2/service/athena" "github.com/aws/aws-sdk-go-v2/service/autoscaling" "github.com/aws/aws-sdk-go-v2/service/backup" @@ -132,6 +133,11 @@ type Apigatewayv2Client interface { GetTags(ctx context.Context, params *apigatewayv2.GetTagsInput, optFns ...func(*apigatewayv2.Options)) (*apigatewayv2.GetTagsOutput, error) } +//go:generate mockgen -package=mocks -destination=./mocks/mock_appsync.go . AppSyncClient +type AppSyncClient interface { + ListGraphqlApis(ctx context.Context, params *appsync.ListGraphqlApisInput, optFns ...func(*appsync.Options)) (*appsync.ListGraphqlApisOutput, error) +} + //go:generate mockgen -package=mocks -destination=./mocks/mock_athena.go . AthenaClient type AthenaClient interface { ListDataCatalogs(ctx context.Context, params *athena.ListDataCatalogsInput, optFns ...func(*athena.Options)) (*athena.ListDataCatalogsOutput, error) diff --git a/docs/tables/aws_appsync_graphql_api_additional_authentication_providers.md b/docs/tables/aws_appsync_graphql_api_additional_authentication_providers.md new file mode 100644 index 000000000..29ff1f7f5 --- /dev/null +++ b/docs/tables/aws_appsync_graphql_api_additional_authentication_providers.md @@ -0,0 +1,18 @@ + +# Table: aws_appsync_graphql_api_additional_authentication_providers +Describes an additional authentication provider +## Columns +| Name | Type | Description | +| ------------- | ------------- | ----- | +|graphql_api_cq_id|uuid|Unique CloudQuery ID of aws_appsync_graphql_apis table (FK)| +|authentication_type|text|The authentication type: API key, Identity and Access Management (IAM), OpenID Connect (OIDC), Amazon Cognito user pools, or Lambda| +|lambda_authorizer_config_authorizer_uri|text|The Amazon Resource Name (ARN) of the Lambda function to be called for authorization| +|lambda_authorizer_config_authorizer_result_ttl_in_seconds|bigint|The number of seconds a response should be cached for| +|lambda_authorizer_config_identity_validation_expression|text|A regular expression for validation of tokens before the Lambda function is called| +|open_id_connect_config_issuer|text|The issuer for the OIDC configuration| +|open_id_connect_config_auth_ttl|bigint|The number of milliseconds that a token is valid after being authenticated| +|open_id_connect_config_client_id|text|The client identifier of the relying party at the OpenID identity provider| +|open_id_connect_config_iat_ttl|bigint|The number of milliseconds that a token is valid after it's issued to a user| +|user_pool_config_aws_region|text|The Amazon Web Services Region in which the user pool was created| +|user_pool_config_user_pool_id|text|The user pool ID| +|user_pool_config_app_id_client_regex|text|A regular expression for validating the incoming Amazon Cognito user pool app client ID| diff --git a/docs/tables/aws_appsync_graphql_apis.md b/docs/tables/aws_appsync_graphql_apis.md new file mode 100644 index 000000000..78b9bd601 --- /dev/null +++ b/docs/tables/aws_appsync_graphql_apis.md @@ -0,0 +1,30 @@ + +# Table: aws_appsync_graphql_apis +Describes a GraphQL API +## Columns +| Name | Type | Description | +| ------------- | ------------- | ----- | +|account_id|text|The AWS Account ID of the resource.| +|region|text|The AWS Region of the resource.| +|id|text|The API ID| +|arn|text|The Amazon Resource Name (ARN)| +|authentication_type|text|The authentication type| +|lambda_authorizer_config_authorizer_uri|text|The Amazon Resource Name (ARN) of the Lambda function to be called for authorization| +|lambda_authorizer_config_authorizer_result_ttl_in_seconds|bigint|The number of seconds a response should be cached for| +|lambda_authorizer_config_identity_validation_expression|text|A regular expression for validation of tokens before the Lambda function is called| +|log_config_cloud_watch_logs_role_arn|text|The service role that AppSync assumes to publish to CloudWatch logs in your account| +|log_config_field_log_level|text|The field logging level| +|log_config_exclude_verbose_content|boolean|Set to TRUE to exclude sections that contain information such as headers, context, and evaluated mapping templates, regardless of logging level| +|name|text|The API name| +|open_id_connect_config_issuer|text|The issuer for the OIDC configuration| +|open_id_connect_config_auth_ttl|bigint|The number of milliseconds that a token is valid after being authenticated| +|open_id_connect_config_client_id|text|The client identifier of the relying party at the OpenID identity provider| +|open_id_connect_config_iat_ttl|bigint|The number of milliseconds that a token is valid after it's issued to a user| +|tags|jsonb|The tags| +|uris|jsonb|The URIs| +|user_pool_config_aws_region|text|The Amazon Web Services Region in which the user pool was created| +|user_pool_config_default_action|text|The action that you want your GraphQL API to take when a request that uses Amazon Cognito user pool authentication doesn't match the Amazon Cognito user pool configuration| +|user_pool_config_user_pool_id|text|The user pool ID| +|user_pool_config_app_id_client_regex|text|A regular expression for validating the incoming Amazon Cognito user pool app client ID| +|waf_web_acl_arn|text|The ARN of the WAF access control list (ACL) associated with this GraphqlApi, if one exists| +|xray_enabled|boolean|A flag indicating whether to use X-Ray tracing for this GraphqlApi| diff --git a/go.mod b/go.mod index f61ae288e..5aea81178 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/cloudquery/cq-provider-aws go 1.18 require ( - github.com/aws/aws-sdk-go-v2 v1.16.7 + github.com/aws/aws-sdk-go-v2 v1.16.8 github.com/aws/aws-sdk-go-v2/config v1.15.14 github.com/aws/aws-sdk-go-v2/credentials v1.12.9 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.20 @@ -12,6 +12,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/apigateway v1.15.10 github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.12.8 github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.15.8 + github.com/aws/aws-sdk-go-v2/service/appsync v1.15.1 github.com/aws/aws-sdk-go-v2/service/autoscaling v1.23.5 github.com/aws/aws-sdk-go-v2/service/cloudformation v1.21.2 github.com/aws/aws-sdk-go-v2/service/cloudfront v1.18.4 @@ -103,8 +104,8 @@ require ( github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15 // indirect github.com/aws/aws-sdk-go-v2/service/athena v1.16.0 github.com/aws/aws-sdk-go-v2/service/backup v1.16.3 diff --git a/go.sum b/go.sum index d3573f94d..2dd5d2868 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,9 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/aws/aws-sdk-go-v2 v1.16.6/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= -github.com/aws/aws-sdk-go-v2 v1.16.7 h1:zfBwXus3u14OszRxGcqCDS4MfMCv10e8SMJ2r8Xm0Ns= github.com/aws/aws-sdk-go-v2 v1.16.7/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= +github.com/aws/aws-sdk-go-v2 v1.16.8 h1:gOe9UPR98XSf7oEJCcojYg+N2/jCRm4DdeIsP85pIyQ= +github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 h1:S/ZBwevQkr7gv5YxONYpGQxlMFFYSRfz3RMcjsC9Qhk= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y= github.com/aws/aws-sdk-go-v2/config v1.15.14 h1:+BqpqlydTq4c2et9Daury7gE+o67P4lbk7eybiCBNc4= @@ -68,11 +69,13 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.8/go.mod h1:oL1Q3KuCq1D4NykQ github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.20 h1:J7/+NFr8N7ebaC/Khie8ptnWn0h436q1hblMeL53mww= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.20/go.mod h1:IOgK2DAat3WO2qAaPmIzTdF+QqL18samL3dqZdjRBZI= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.13/go.mod h1:wLLesU+LdMZDM3U0PP9vZXJW39zmD/7L4nY2pSrYZ/g= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14 h1:2C0pYHcUBmdzPj+EKNC4qj97oK6yjrUhc1KoSodglvk= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14/go.mod h1:kdjrMwHwrC3+FsKhNcCMJ7tUVj/8uSD5CZXeQ4wV6fM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15 h1:bx5F2mr6H6FC7zNIQoDoUr8wEKnvmwRncujT3FYRtic= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.7/go.mod h1:93Uot80ddyVzSl//xEJreNKMhxntr71WtR3v/A1cRYk= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8 h1:2J+jdlBJWEmTyAwC82Ym68xCykIvnSnIN18b8xHGlcc= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8/go.mod h1:ZIV8GYoC6WLBW5KGs+o4rsc65/ozd+eQ0L31XF5VDwk= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9 h1:5sbyznZC2TeFpa4fvtpvpcGbzeXEEs1l1Jo51ynUNsQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9/go.mod h1:08tUpeSGN33QKSO7fwxXczNfiwCpbj+GxK6XKwqWVv0= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15 h1:QquxR7NH3ULBsKC+NoTpilzbKKS+5AELfNREInbhvas= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15/go.mod h1:Tkrthp/0sNBShQQsamR7j/zY4p19tVTAs+nnqhH6R3c= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.5 h1:tEEHn+PGAxRVqMPEhtU8oCSW/1Ge3zP5nUgPrGQNUPs= @@ -87,6 +90,8 @@ github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.12.8 h1:OQZODVKX58BBVtiGHdQ github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.12.8/go.mod h1:YXBCG4l+2VBAd1a634Pz/iJvlTwKaTkdkj/BmtdS4X4= github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.15.8 h1:obyX/RxIav+YBLkfW8wfD6f5XlHowqjJ9vYAwx+aogs= github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.15.8/go.mod h1:289SWqwukb06IipOqjpcZYNiPNW4SH3wYKQPfpJXa1M= +github.com/aws/aws-sdk-go-v2/service/appsync v1.15.1 h1:Y6aON7pWXCv8Y68WF66qjE9ZPnTOWaAh32RG/Lcb2cI= +github.com/aws/aws-sdk-go-v2/service/appsync v1.15.1/go.mod h1:TfdM7u85zDQdH2WoGf07FBhNIL3jrBD8AYHAlab96aA= github.com/aws/aws-sdk-go-v2/service/athena v1.16.0 h1:QAejbkyqK2Z8bOtitlUt7/I/uTV08PvEiAzccfmGTkM= github.com/aws/aws-sdk-go-v2/service/athena v1.16.0/go.mod h1:uJUguNgKmnxoP19GOdVbPvEFNku5uV9guO0Dt+V3oB4= github.com/aws/aws-sdk-go-v2/service/autoscaling v1.23.5 h1:bOzF892bRTvBgcN3qgZ4KZZCAp8Gl7pWUxivVeJlR/0= diff --git a/resources/provider/provider.go b/resources/provider/provider.go index 3c6fdcbc5..d506dcd58 100644 --- a/resources/provider/provider.go +++ b/resources/provider/provider.go @@ -9,6 +9,7 @@ import ( "github.com/cloudquery/cq-provider-aws/resources/services/apigateway" "github.com/cloudquery/cq-provider-aws/resources/services/apigatewayv2" "github.com/cloudquery/cq-provider-aws/resources/services/applicationautoscaling" + "github.com/cloudquery/cq-provider-aws/resources/services/appsync" "github.com/cloudquery/cq-provider-aws/resources/services/athena" "github.com/cloudquery/cq-provider-aws/resources/services/autoscaling" "github.com/cloudquery/cq-provider-aws/resources/services/backup" @@ -95,6 +96,7 @@ func Provider() *provider.Provider { "apigatewayv2.domain_names": apigatewayv2.Apigatewayv2DomainNames(), "apigatewayv2.vpc_links": apigatewayv2.Apigatewayv2VpcLinks(), "applicationautoscaling.policies": applicationautoscaling.ApplicationautoscalingPolicies(), + "appsync.graphql_apis": appsync.GraphqlApis(), "athena.data_catalogs": athena.DataCatalogs(), "athena.work_groups": athena.WorkGroups(), "autoscaling.groups": autoscaling.AutoscalingGroups(), diff --git a/resources/services/appsync/gen.hcl b/resources/services/appsync/gen.hcl new file mode 100644 index 000000000..7fe478a65 --- /dev/null +++ b/resources/services/appsync/gen.hcl @@ -0,0 +1,45 @@ +service = "aws" +output_directory = "." +add_generate = true + +description_modifier "remove_read_only" { + words = [" This member is required."] +} + +resource "aws" "appsync" "graphql_apis" { + path = "github.com/aws/aws-sdk-go-v2/service/appsync/types.GraphqlApi" + + ignoreError "IgnoreCommonErrors" { + path = "github.com/cloudquery/cq-provider-aws/client.IgnoreCommonErrors" + } + multiplex "AwsAccountRegion" { + path = "github.com/cloudquery/cq-provider-aws/client.ServiceAccountRegionMultiplexer" + params = ["appsync"] + } + deleteFilter "AccountRegionFilter" { + path = "github.com/cloudquery/cq-provider-aws/client.DeleteAccountRegionFilter" + } + + options { + primary_keys = ["arn"] + } + + column "api_id" { + rename = "id" + } + + userDefinedColumn "account_id" { + type = "string" + description = "The AWS Account ID of the resource." + resolver "resolveAWSAccount" { + path = "github.com/cloudquery/cq-provider-aws/client.ResolveAWSAccount" + } + } + userDefinedColumn "region" { + type = "string" + description = "The AWS Region of the resource." + resolver "resolveAWSRegion" { + path = "github.com/cloudquery/cq-provider-aws/client.ResolveAWSRegion" + } + } +} \ No newline at end of file diff --git a/resources/services/appsync/graphql_apis.go b/resources/services/appsync/graphql_apis.go new file mode 100644 index 000000000..001c44b88 --- /dev/null +++ b/resources/services/appsync/graphql_apis.go @@ -0,0 +1,267 @@ +package appsync + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/appsync" + "github.com/cloudquery/cq-provider-aws/client" + "github.com/cloudquery/cq-provider-sdk/provider/diag" + "github.com/cloudquery/cq-provider-sdk/provider/schema" +) + +//go:generate cq-gen --resource graphql_apis --config gen.hcl --output . +func GraphqlApis() *schema.Table { + return &schema.Table{ + Name: "aws_appsync_graphql_apis", + Description: "Describes a GraphQL API", + Resolver: fetchAppsyncGraphqlApis, + Multiplex: client.ServiceAccountRegionMultiplexer("appsync"), + IgnoreError: client.IgnoreCommonErrors, + DeleteFilter: client.DeleteAccountRegionFilter, + Options: schema.TableCreationOptions{PrimaryKeys: []string{"arn"}}, + Columns: []schema.Column{ + { + Name: "account_id", + Description: "The AWS Account ID of the resource.", + Type: schema.TypeString, + Resolver: client.ResolveAWSAccount, + }, + { + Name: "region", + Description: "The AWS Region of the resource.", + Type: schema.TypeString, + Resolver: client.ResolveAWSRegion, + }, + { + Name: "id", + Description: "The API ID", + Type: schema.TypeString, + Resolver: schema.PathResolver("ApiId"), + }, + { + Name: "arn", + Description: "The Amazon Resource Name (ARN)", + Type: schema.TypeString, + }, + { + Name: "authentication_type", + Description: "The authentication type", + Type: schema.TypeString, + }, + { + Name: "lambda_authorizer_config_authorizer_uri", + Description: "The Amazon Resource Name (ARN) of the Lambda function to be called for authorization", + Type: schema.TypeString, + Resolver: schema.PathResolver("LambdaAuthorizerConfig.AuthorizerUri"), + }, + { + Name: "lambda_authorizer_config_authorizer_result_ttl_in_seconds", + Description: "The number of seconds a response should be cached for", + Type: schema.TypeBigInt, + Resolver: schema.PathResolver("LambdaAuthorizerConfig.AuthorizerResultTtlInSeconds"), + }, + { + Name: "lambda_authorizer_config_identity_validation_expression", + Description: "A regular expression for validation of tokens before the Lambda function is called", + Type: schema.TypeString, + Resolver: schema.PathResolver("LambdaAuthorizerConfig.IdentityValidationExpression"), + }, + { + Name: "log_config_cloud_watch_logs_role_arn", + Description: "The service role that AppSync assumes to publish to CloudWatch logs in your account", + Type: schema.TypeString, + Resolver: schema.PathResolver("LogConfig.CloudWatchLogsRoleArn"), + }, + { + Name: "log_config_field_log_level", + Description: "The field logging level", + Type: schema.TypeString, + Resolver: schema.PathResolver("LogConfig.FieldLogLevel"), + }, + { + Name: "log_config_exclude_verbose_content", + Description: "Set to TRUE to exclude sections that contain information such as headers, context, and evaluated mapping templates, regardless of logging level", + Type: schema.TypeBool, + Resolver: schema.PathResolver("LogConfig.ExcludeVerboseContent"), + }, + { + Name: "name", + Description: "The API name", + Type: schema.TypeString, + }, + { + Name: "open_id_connect_config_issuer", + Description: "The issuer for the OIDC configuration", + Type: schema.TypeString, + Resolver: schema.PathResolver("OpenIDConnectConfig.Issuer"), + }, + { + Name: "open_id_connect_config_auth_ttl", + Description: "The number of milliseconds that a token is valid after being authenticated", + Type: schema.TypeBigInt, + Resolver: schema.PathResolver("OpenIDConnectConfig.AuthTTL"), + }, + { + Name: "open_id_connect_config_client_id", + Description: "The client identifier of the relying party at the OpenID identity provider", + Type: schema.TypeString, + Resolver: schema.PathResolver("OpenIDConnectConfig.ClientId"), + }, + { + Name: "open_id_connect_config_iat_ttl", + Description: "The number of milliseconds that a token is valid after it's issued to a user", + Type: schema.TypeBigInt, + Resolver: schema.PathResolver("OpenIDConnectConfig.IatTTL"), + }, + { + Name: "tags", + Description: "The tags", + Type: schema.TypeJSON, + }, + { + Name: "uris", + Description: "The URIs", + Type: schema.TypeJSON, + }, + { + Name: "user_pool_config_aws_region", + Description: "The Amazon Web Services Region in which the user pool was created", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserPoolConfig.AwsRegion"), + }, + { + Name: "user_pool_config_default_action", + Description: "The action that you want your GraphQL API to take when a request that uses Amazon Cognito user pool authentication doesn't match the Amazon Cognito user pool configuration", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserPoolConfig.DefaultAction"), + }, + { + Name: "user_pool_config_user_pool_id", + Description: "The user pool ID", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserPoolConfig.UserPoolId"), + }, + { + Name: "user_pool_config_app_id_client_regex", + Description: "A regular expression for validating the incoming Amazon Cognito user pool app client ID", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserPoolConfig.AppIdClientRegex"), + }, + { + Name: "waf_web_acl_arn", + Description: "The ARN of the WAF access control list (ACL) associated with this GraphqlApi, if one exists", + Type: schema.TypeString, + }, + { + Name: "xray_enabled", + Description: "A flag indicating whether to use X-Ray tracing for this GraphqlApi", + Type: schema.TypeBool, + }, + }, + Relations: []*schema.Table{ + { + Name: "aws_appsync_graphql_api_additional_authentication_providers", + Description: "Describes an additional authentication provider", + Resolver: schema.PathTableResolver("AdditionalAuthenticationProviders"), + Columns: []schema.Column{ + { + Name: "graphql_api_cq_id", + Description: "Unique CloudQuery ID of aws_appsync_graphql_apis table (FK)", + Type: schema.TypeUUID, + Resolver: schema.ParentIdResolver, + }, + { + Name: "authentication_type", + Description: "The authentication type: API key, Identity and Access Management (IAM), OpenID Connect (OIDC), Amazon Cognito user pools, or Lambda", + Type: schema.TypeString, + }, + { + Name: "lambda_authorizer_config_authorizer_uri", + Description: "The Amazon Resource Name (ARN) of the Lambda function to be called for authorization", + Type: schema.TypeString, + Resolver: schema.PathResolver("LambdaAuthorizerConfig.AuthorizerUri"), + }, + { + Name: "lambda_authorizer_config_authorizer_result_ttl_in_seconds", + Description: "The number of seconds a response should be cached for", + Type: schema.TypeBigInt, + Resolver: schema.PathResolver("LambdaAuthorizerConfig.AuthorizerResultTtlInSeconds"), + }, + { + Name: "lambda_authorizer_config_identity_validation_expression", + Description: "A regular expression for validation of tokens before the Lambda function is called", + Type: schema.TypeString, + Resolver: schema.PathResolver("LambdaAuthorizerConfig.IdentityValidationExpression"), + }, + { + Name: "open_id_connect_config_issuer", + Description: "The issuer for the OIDC configuration", + Type: schema.TypeString, + Resolver: schema.PathResolver("OpenIDConnectConfig.Issuer"), + }, + { + Name: "open_id_connect_config_auth_ttl", + Description: "The number of milliseconds that a token is valid after being authenticated", + Type: schema.TypeBigInt, + Resolver: schema.PathResolver("OpenIDConnectConfig.AuthTTL"), + }, + { + Name: "open_id_connect_config_client_id", + Description: "The client identifier of the relying party at the OpenID identity provider", + Type: schema.TypeString, + Resolver: schema.PathResolver("OpenIDConnectConfig.ClientId"), + }, + { + Name: "open_id_connect_config_iat_ttl", + Description: "The number of milliseconds that a token is valid after it's issued to a user", + Type: schema.TypeBigInt, + Resolver: schema.PathResolver("OpenIDConnectConfig.IatTTL"), + }, + { + Name: "user_pool_config_aws_region", + Description: "The Amazon Web Services Region in which the user pool was created", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserPoolConfig.AwsRegion"), + }, + { + Name: "user_pool_config_user_pool_id", + Description: "The user pool ID", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserPoolConfig.UserPoolId"), + }, + { + Name: "user_pool_config_app_id_client_regex", + Description: "A regular expression for validating the incoming Amazon Cognito user pool app client ID", + Type: schema.TypeString, + Resolver: schema.PathResolver("UserPoolConfig.AppIdClientRegex"), + }, + }, + }, + }, + } +} + +// ==================================================================================================================== +// Table Resolver Functions +// ==================================================================================================================== + +func fetchAppsyncGraphqlApis(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- interface{}) error { + var config appsync.ListGraphqlApisInput + c := meta.(*client.Client) + svc := c.Services().AppSync + for { + output, err := svc.ListGraphqlApis(ctx, &config, func(options *appsync.Options) { + options.Region = c.Region + }) + if err != nil { + return diag.WrapError(err) + } + res <- output.GraphqlApis + if aws.ToString(output.NextToken) == "" { + break + } + config.NextToken = output.NextToken + } + return nil +} diff --git a/resources/services/appsync/graphql_apis_mock_test.go b/resources/services/appsync/graphql_apis_mock_test.go new file mode 100644 index 000000000..58e268921 --- /dev/null +++ b/resources/services/appsync/graphql_apis_mock_test.go @@ -0,0 +1,34 @@ +package appsync + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/service/appsync" + "github.com/aws/aws-sdk-go-v2/service/appsync/types" + "github.com/cloudquery/cq-provider-aws/client" + "github.com/cloudquery/cq-provider-aws/client/mocks" + "github.com/cloudquery/faker/v3" + "github.com/golang/mock/gomock" +) + +func buildAppsyncGraphqlApisMock(t *testing.T, ctrl *gomock.Controller) client.Services { + m := mocks.NewMockAppSyncClient(ctrl) + l := types.GraphqlApi{} + err := faker.FakeData(&l) + if err != nil { + t.Fatal(err) + } + + m.EXPECT().ListGraphqlApis(gomock.Any(), gomock.Any(), gomock.Any()).Return( + &appsync.ListGraphqlApisOutput{ + GraphqlApis: []types.GraphqlApi{l}, + }, nil) + + return client.Services{ + AppSync: m, + } +} + +func TestAppSyncGraphqlApis(t *testing.T) { + client.AwsMockTestHelper(t, GraphqlApis(), buildAppsyncGraphqlApisMock, client.TestOptions{}) +} diff --git a/terraform/appsync/local/main.tf b/terraform/appsync/local/main.tf new file mode 100644 index 000000000..21bb27978 --- /dev/null +++ b/terraform/appsync/local/main.tf @@ -0,0 +1,4 @@ +module "demo" { + source = "../modules/test" + prefix = var.prefix +} \ No newline at end of file diff --git a/terraform/appsync/local/variables.tf b/terraform/appsync/local/variables.tf new file mode 100644 index 000000000..97b504923 --- /dev/null +++ b/terraform/appsync/local/variables.tf @@ -0,0 +1,8 @@ +variable "prefix" { + description = "Prefix to use for all name resources" + type = string + validation { + condition = length(var.prefix) == 2 + error_message = "The prefix should be exactly two characters." + } +} diff --git a/terraform/appsync/modules/test/appsync.tf b/terraform/appsync/modules/test/appsync.tf new file mode 100644 index 000000000..62f17ff85 --- /dev/null +++ b/terraform/appsync/modules/test/appsync.tf @@ -0,0 +1,6 @@ +module "appsync" { + source = "terraform-aws-modules/appsync/aws" + version = "1.5.2" + name = "${var.prefix}-appsync" + tags = var.tags +} diff --git a/terraform/appsync/modules/test/provider.tf b/terraform/appsync/modules/test/provider.tf new file mode 100644 index 000000000..e70fb2fc9 --- /dev/null +++ b/terraform/appsync/modules/test/provider.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "us-east-1" +} \ No newline at end of file diff --git a/terraform/appsync/modules/test/terraform.tf b/terraform/appsync/modules/test/terraform.tf new file mode 100644 index 000000000..0518c15da --- /dev/null +++ b/terraform/appsync/modules/test/terraform.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 0.15" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.74.0" + } + } +} \ No newline at end of file diff --git a/terraform/appsync/modules/test/variables.tf b/terraform/appsync/modules/test/variables.tf new file mode 100644 index 000000000..456eb670d --- /dev/null +++ b/terraform/appsync/modules/test/variables.tf @@ -0,0 +1,15 @@ +variable "prefix" { + description = "Prefix to use for all name resources" + type = string + validation { + condition = length(var.prefix) == 2 + error_message = "The prefix should be exactly two characters." + } +} + +variable "tags" { + type = map(any) + default = { + Environment = "cq-provider-aws" + } +} diff --git a/terraform/appsync/prod/main.tf b/terraform/appsync/prod/main.tf new file mode 100644 index 000000000..380fd1e95 --- /dev/null +++ b/terraform/appsync/prod/main.tf @@ -0,0 +1,4 @@ +module "demo" { + source = "../modules/test" + prefix = "cq" +} \ No newline at end of file diff --git a/terraform/appsync/prod/terraform.tf b/terraform/appsync/prod/terraform.tf new file mode 100644 index 000000000..ac6e375dd --- /dev/null +++ b/terraform/appsync/prod/terraform.tf @@ -0,0 +1,7 @@ +terraform { + backend "s3" { + bucket = "cq-provider-aws-tf" + key = "appsync" + region = "us-east-1" + } +}