diff --git a/plugins/source/aws/codegen/recipes/elasticsearch.go b/plugins/source/aws/codegen/recipes/elasticsearch.go index b7710d4eb93664..a590083ca90581 100644 --- a/plugins/source/aws/codegen/recipes/elasticsearch.go +++ b/plugins/source/aws/codegen/recipes/elasticsearch.go @@ -10,17 +10,58 @@ func ElasticsearchResources() []*Resource { resources := []*Resource{ { SubService: "domains", - Struct: &types.ElasticsearchDomainStatus{}, + Struct: new(types.ElasticsearchDomainStatus), + Description: "https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_DomainStatus.html", PreResourceResolver: "getDomain", PKColumns: []string{"arn"}, - ExtraColumns: append(defaultRegionalColumns, + ExtraColumns: append( + defaultRegionalColumns, + codegen.ColumnDefinition{ + Name: "authorized_principals", + Type: schema.TypeJSON, + Resolver: `resolveAuthorizedPrincipals`, + }, codegen.ColumnDefinition{ Name: "tags", Type: schema.TypeJSON, - Resolver: `resolveTags`, + Resolver: `resolveDomainTags`, }, ), }, + { + SubService: "packages", + Struct: new(types.PackageDetails), + Description: "https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_PackageDetails.html", + NameTransformer: CreateReplaceTransformer(map[string]string{"package_id": "id"}), + PKColumns: []string{"id"}, + ExtraColumns: defaultRegionalColumnsPK, + }, + { + SubService: "versions", + Struct: new(struct{}), + Description: "https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_ListVersions.html", + PKColumns: []string{"version"}, + ExtraColumns: append(defaultRegionalColumnsPK, + codegen.ColumnDefinition{ + Name: "version", + Type: schema.TypeString, + Resolver: `resolveVersion`, + }, + codegen.ColumnDefinition{ + Name: "instance_types", + Type: schema.TypeJSON, + Resolver: `resolveInstanceTypes`, + }, + ), + }, + { + SubService: "vpc_endpoints", + Struct: new(types.VpcEndpoint), + Description: "https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_VpcEndpoint.html", + NameTransformer: CreateReplaceTransformer(map[string]string{"vpc_endpoint_id": "id"}), + PKColumns: []string{"id"}, + ExtraColumns: defaultRegionalColumns, + }, } // set default values diff --git a/plugins/source/aws/docs/tables/README.md b/plugins/source/aws/docs/tables/README.md index ca91558b7bd68c..d0e11b997e83e8 100644 --- a/plugins/source/aws/docs/tables/README.md +++ b/plugins/source/aws/docs/tables/README.md @@ -195,6 +195,9 @@ - [aws_elasticbeanstalk_configuration_settings](aws_elasticbeanstalk_configuration_settings.md) - [aws_elasticbeanstalk_configuration_options](aws_elasticbeanstalk_configuration_options.md) - [aws_elasticsearch_domains](aws_elasticsearch_domains.md) +- [aws_elasticsearch_packages](aws_elasticsearch_packages.md) +- [aws_elasticsearch_versions](aws_elasticsearch_versions.md) +- [aws_elasticsearch_vpc_endpoints](aws_elasticsearch_vpc_endpoints.md) - [aws_elastictranscoder_pipelines](aws_elastictranscoder_pipelines.md) - [aws_elastictranscoder_pipeline_jobs](aws_elastictranscoder_pipeline_jobs.md) - [aws_elastictranscoder_presets](aws_elastictranscoder_presets.md) diff --git a/plugins/source/aws/docs/tables/aws_elasticsearch_domains.md b/plugins/source/aws/docs/tables/aws_elasticsearch_domains.md index 352aa8ac912078..56fe7b616f5e3f 100644 --- a/plugins/source/aws/docs/tables/aws_elasticsearch_domains.md +++ b/plugins/source/aws/docs/tables/aws_elasticsearch_domains.md @@ -1,5 +1,7 @@ # Table: aws_elasticsearch_domains +https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_DomainStatus.html + The primary key for this table is **arn**. ## Columns @@ -12,6 +14,7 @@ The primary key for this table is **arn**. |_cq_parent_id|UUID| |account_id|String| |region|String| +|authorized_principals|JSON| |tags|JSON| |arn (PK)|String| |domain_id|String| diff --git a/plugins/source/aws/docs/tables/aws_elasticsearch_packages.md b/plugins/source/aws/docs/tables/aws_elasticsearch_packages.md new file mode 100644 index 00000000000000..24ac957a539793 --- /dev/null +++ b/plugins/source/aws/docs/tables/aws_elasticsearch_packages.md @@ -0,0 +1,25 @@ +# Table: aws_elasticsearch_packages + +https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_PackageDetails.html + +The composite primary key for this table is (**account_id**, **region**, **id**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|account_id (PK)|String| +|region (PK)|String| +|available_package_version|String| +|created_at|Timestamp| +|error_details|JSON| +|last_updated_at|Timestamp| +|package_description|String| +|id (PK)|String| +|package_name|String| +|package_status|String| +|package_type|String| \ No newline at end of file diff --git a/plugins/source/aws/docs/tables/aws_elasticsearch_versions.md b/plugins/source/aws/docs/tables/aws_elasticsearch_versions.md new file mode 100644 index 00000000000000..db0fffa3cf6339 --- /dev/null +++ b/plugins/source/aws/docs/tables/aws_elasticsearch_versions.md @@ -0,0 +1,18 @@ +# Table: aws_elasticsearch_versions + +https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_ListVersions.html + +The composite primary key for this table is (**account_id**, **region**, **version**). + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|account_id (PK)|String| +|region (PK)|String| +|version (PK)|String| +|instance_types|JSON| \ No newline at end of file diff --git a/plugins/source/aws/docs/tables/aws_elasticsearch_vpc_endpoints.md b/plugins/source/aws/docs/tables/aws_elasticsearch_vpc_endpoints.md new file mode 100644 index 00000000000000..ed413a3ba7e7aa --- /dev/null +++ b/plugins/source/aws/docs/tables/aws_elasticsearch_vpc_endpoints.md @@ -0,0 +1,22 @@ +# Table: aws_elasticsearch_vpc_endpoints + +https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_VpcEndpoint.html + +The primary key for this table is **id**. + +## Columns + +| Name | Type | +| ------------- | ------------- | +|_cq_source_name|String| +|_cq_sync_time|Timestamp| +|_cq_id|UUID| +|_cq_parent_id|UUID| +|account_id|String| +|region|String| +|domain_arn|String| +|endpoint|String| +|status|String| +|id (PK)|String| +|vpc_endpoint_owner|String| +|vpc_options|JSON| \ No newline at end of file diff --git a/plugins/source/aws/resources/plugin/tables.go b/plugins/source/aws/resources/plugin/tables.go index cee4a21102c2a3..61b8dba5117436 100644 --- a/plugins/source/aws/resources/plugin/tables.go +++ b/plugins/source/aws/resources/plugin/tables.go @@ -227,6 +227,9 @@ func tables() []*schema.Table { elasticbeanstalk.Applications(), elasticbeanstalk.Environments(), elasticsearch.Domains(), + elasticsearch.Packages(), + elasticsearch.Versions(), + elasticsearch.VpcEndpoints(), elastictranscoder.Pipelines(), elastictranscoder.Presets(), elbv1.LoadBalancers(), diff --git a/plugins/source/aws/resources/services/elasticsearch/domains.go b/plugins/source/aws/resources/services/elasticsearch/domains.go index 58a50aa512dbce..9aca73aecf8306 100644 --- a/plugins/source/aws/resources/services/elasticsearch/domains.go +++ b/plugins/source/aws/resources/services/elasticsearch/domains.go @@ -10,6 +10,7 @@ import ( func Domains() *schema.Table { return &schema.Table{ Name: "aws_elasticsearch_domains", + Description: `https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_DomainStatus.html`, Resolver: fetchElasticsearchDomains, PreResourceResolver: getDomain, Multiplex: client.ServiceAccountRegionMultiplexer("es"), @@ -24,10 +25,15 @@ func Domains() *schema.Table { Type: schema.TypeString, Resolver: client.ResolveAWSRegion, }, + { + Name: "authorized_principals", + Type: schema.TypeJSON, + Resolver: resolveAuthorizedPrincipals, + }, { Name: "tags", Type: schema.TypeJSON, - Resolver: resolveTags, + Resolver: resolveDomainTags, }, { Name: "arn", diff --git a/plugins/source/aws/resources/services/elasticsearch/domains_fetch.go b/plugins/source/aws/resources/services/elasticsearch/domains_fetch.go index 19dcd49a7a7646..4b5b164d2c3dbc 100644 --- a/plugins/source/aws/resources/services/elasticsearch/domains_fetch.go +++ b/plugins/source/aws/resources/services/elasticsearch/domains_fetch.go @@ -10,28 +10,72 @@ import ( ) func fetchElasticsearchDomains(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { - c := meta.(*client.Client) - svc := c.Services().Elasticsearchservice - out, err := svc.ListDomainNames(ctx, &elasticsearchservice.ListDomainNamesInput{}) + svc := meta.(*client.Client).Services().Elasticsearchservice + + out, err := svc.ListDomainNames(ctx, nil) if err != nil { return err } res <- out.DomainNames + return nil } func getDomain(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource) error { - c := meta.(*client.Client) - svc := c.Services().Elasticsearchservice - - info := resource.Item.(types.DomainInfo) + svc := meta.(*client.Client).Services().Elasticsearchservice - domainOutput, err := svc.DescribeElasticsearchDomain(ctx, &elasticsearchservice.DescribeElasticsearchDomainInput{DomainName: info.DomainName}) + out, err := svc.DescribeElasticsearchDomain(ctx, + &elasticsearchservice.DescribeElasticsearchDomainInput{ + DomainName: resource.Item.(types.DomainInfo).DomainName, + }, + ) if err != nil { - return nil + return err } - resource.Item = domainOutput.DomainStatus + resource.SetItem(out.DomainStatus) + return nil } + +func resolveDomainTags(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, c schema.Column) error { + svc := meta.(*client.Client).Services().Elasticsearchservice + + tagsOutput, err := svc.ListTags(ctx, + &elasticsearchservice.ListTagsInput{ + ARN: resource.Item.(*types.ElasticsearchDomainStatus).ARN, + }, + ) + if err != nil { + return err + } + + return resource.Set(c.Name, client.TagsToMap(tagsOutput.TagList)) +} + +func resolveAuthorizedPrincipals(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, c schema.Column) error { + svc := meta.(*client.Client).Services().Elasticsearchservice + + input := &elasticsearchservice.ListVpcEndpointAccessInput{ + DomainName: resource.Item.(*types.ElasticsearchDomainStatus).DomainName, + } + + var principals []types.AuthorizedPrincipal + for { + out, err := svc.ListVpcEndpointAccess(ctx, input) + if err != nil { + return err + } + + principals = append(principals, out.AuthorizedPrincipalList...) + + if out.NextToken == nil { + break + } + + input.NextToken = out.NextToken + } + + return resource.Set(c.Name, principals) +} diff --git a/plugins/source/aws/resources/services/elasticsearch/domains_mock_test.go b/plugins/source/aws/resources/services/elasticsearch/domains_mock_test.go index efff6298b0d8a9..707a3c6326b084 100644 --- a/plugins/source/aws/resources/services/elasticsearch/domains_mock_test.go +++ b/plugins/source/aws/resources/services/elasticsearch/domains_mock_test.go @@ -14,24 +14,44 @@ import ( func buildElasticSearchDomains(t *testing.T, ctrl *gomock.Controller) client.Services { m := mocks.NewMockElasticsearchserviceClient(ctrl) - var di types.DomainInfo - if err := faker.FakeObject(&di); err != nil { + var info types.DomainInfo + if err := faker.FakeObject(&info); err != nil { t.Fatal(err) } - m.EXPECT().ListDomainNames(gomock.Any(), &elasticsearchservice.ListDomainNamesInput{}, gomock.Any()).Return( - &elasticsearchservice.ListDomainNamesOutput{DomainNames: []types.DomainInfo{di}}, nil) + m.EXPECT().ListDomainNames(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.ListDomainNamesOutput{ + DomainNames: []types.DomainInfo{info}, + }, + nil, + ) var ds types.ElasticsearchDomainStatus if err := faker.FakeObject(&ds); err != nil { t.Fatal(err) } - m.EXPECT().DescribeElasticsearchDomain( - gomock.Any(), - &elasticsearchservice.DescribeElasticsearchDomainInput{DomainName: di.DomainName}, - gomock.Any(), - ).Return(&elasticsearchservice.DescribeElasticsearchDomainOutput{DomainStatus: &ds}, nil) - - addTagsCall(t, m) + m.EXPECT().DescribeElasticsearchDomain(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.DescribeElasticsearchDomainOutput{ + DomainStatus: &ds, + }, + nil, + ) + + var principal types.AuthorizedPrincipal + if err := faker.FakeObject(&principal); err != nil { + t.Fatal(err) + } + m.EXPECT().ListVpcEndpointAccess(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.ListVpcEndpointAccessOutput{ + AuthorizedPrincipalList: []types.AuthorizedPrincipal{principal}, + }, + nil, + ) + + var tags elasticsearchservice.ListTagsOutput + if err := faker.FakeObject(&tags); err != nil { + t.Fatal(err) + } + m.EXPECT().ListTags(gomock.Any(), gomock.Any()).Return(&tags, nil) return client.Services{Elasticsearchservice: m} } diff --git a/plugins/source/aws/resources/services/elasticsearch/packages.go b/plugins/source/aws/resources/services/elasticsearch/packages.go new file mode 100644 index 00000000000000..91c883f02461aa --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/packages.go @@ -0,0 +1,83 @@ +// Code generated by codegen; DO NOT EDIT. + +package elasticsearch + +import ( + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Packages() *schema.Table { + return &schema.Table{ + Name: "aws_elasticsearch_packages", + Description: `https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_PackageDetails.html`, + Resolver: fetchElasticsearchPackages, + Multiplex: client.ServiceAccountRegionMultiplexer("es"), + Columns: []schema.Column{ + { + Name: "account_id", + Type: schema.TypeString, + Resolver: client.ResolveAWSAccount, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "region", + Type: schema.TypeString, + Resolver: client.ResolveAWSRegion, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "available_package_version", + Type: schema.TypeString, + Resolver: schema.PathResolver("AvailablePackageVersion"), + }, + { + Name: "created_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("CreatedAt"), + }, + { + Name: "error_details", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("ErrorDetails"), + }, + { + Name: "last_updated_at", + Type: schema.TypeTimestamp, + Resolver: schema.PathResolver("LastUpdatedAt"), + }, + { + Name: "package_description", + Type: schema.TypeString, + Resolver: schema.PathResolver("PackageDescription"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("PackageID"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "package_name", + Type: schema.TypeString, + Resolver: schema.PathResolver("PackageName"), + }, + { + Name: "package_status", + Type: schema.TypeString, + Resolver: schema.PathResolver("PackageStatus"), + }, + { + Name: "package_type", + Type: schema.TypeString, + Resolver: schema.PathResolver("PackageType"), + }, + }, + } +} diff --git a/plugins/source/aws/resources/services/elasticsearch/packages_fetch.go b/plugins/source/aws/resources/services/elasticsearch/packages_fetch.go new file mode 100755 index 00000000000000..8e10ee4491facb --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/packages_fetch.go @@ -0,0 +1,25 @@ +package elasticsearch + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchElasticsearchPackages(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + svc := meta.(*client.Client).Services().Elasticsearchservice + + p := elasticsearchservice.NewDescribePackagesPaginator(svc, nil) + for p.HasMorePages() { + out, err := p.NextPage(ctx) + if err != nil { + return err + } + + res <- out.PackageDetailsList + } + + return nil +} diff --git a/plugins/source/aws/resources/services/elasticsearch/packages_mock_test.go b/plugins/source/aws/resources/services/elasticsearch/packages_mock_test.go new file mode 100644 index 00000000000000..f234e8b8354d64 --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/packages_mock_test.go @@ -0,0 +1,33 @@ +package elasticsearch + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice/types" + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/cloudquery/plugins/source/aws/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/golang/mock/gomock" +) + +func buildElasticSearchPackages(t *testing.T, ctrl *gomock.Controller) client.Services { + m := mocks.NewMockElasticsearchserviceClient(ctrl) + + var pkg types.PackageDetails + if err := faker.FakeObject(&pkg); err != nil { + t.Fatal(err) + } + m.EXPECT().DescribePackages(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.DescribePackagesOutput{ + PackageDetailsList: []types.PackageDetails{pkg}, + }, + nil, + ) + + return client.Services{Elasticsearchservice: m} +} + +func TestElasticSearchPackages(t *testing.T) { + client.AwsMockTestHelper(t, Packages(), buildElasticSearchPackages, client.TestOptions{}) +} diff --git a/plugins/source/aws/resources/services/elasticsearch/tags_fetch.go b/plugins/source/aws/resources/services/elasticsearch/tags_fetch.go deleted file mode 100644 index 6da9a757aec8b0..00000000000000 --- a/plugins/source/aws/resources/services/elasticsearch/tags_fetch.go +++ /dev/null @@ -1,35 +0,0 @@ -package elasticsearch - -import ( - "context" - "fmt" - - "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" - "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice/types" - "github.com/cloudquery/cloudquery/plugins/source/aws/client" - "github.com/cloudquery/plugin-sdk/schema" -) - -func resolveTags(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, c schema.Column) error { - region := meta.(*client.Client).Region - svc := meta.(*client.Client).Services().Elasticsearchservice - - var arn *string - switch typed := resource.Item.(type) { - case *types.ElasticsearchDomainStatus: - arn = typed.ARN - default: - return fmt.Errorf("unsupported type for resolveTags: %T", typed) - } - - tagsOutput, err := svc.ListTags(ctx, &elasticsearchservice.ListTagsInput{ - ARN: arn, - }, func(o *elasticsearchservice.Options) { - o.Region = region - }) - if err != nil { - return err - } - - return resource.Set(c.Name, client.TagsToMap(tagsOutput.TagList)) -} diff --git a/plugins/source/aws/resources/services/elasticsearch/tags_fetch_mock_test.go b/plugins/source/aws/resources/services/elasticsearch/tags_fetch_mock_test.go deleted file mode 100644 index 87fe8181eb2ba3..00000000000000 --- a/plugins/source/aws/resources/services/elasticsearch/tags_fetch_mock_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package elasticsearch - -import ( - "testing" - - "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" - "github.com/cloudquery/cloudquery/plugins/source/aws/client/mocks" - "github.com/cloudquery/plugin-sdk/faker" - "github.com/golang/mock/gomock" -) - -func addTagsCall(t *testing.T, m *mocks.MockElasticsearchserviceClient) { - var tags elasticsearchservice.ListTagsOutput - if err := faker.FakeObject(&tags); err != nil { - t.Fatal(err) - } - m.EXPECT().ListTags(gomock.Any(), gomock.Any(), gomock.Any()).Return(&tags, nil) -} diff --git a/plugins/source/aws/resources/services/elasticsearch/versions.go b/plugins/source/aws/resources/services/elasticsearch/versions.go new file mode 100644 index 00000000000000..e92597ac79f5e2 --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/versions.go @@ -0,0 +1,48 @@ +// Code generated by codegen; DO NOT EDIT. + +package elasticsearch + +import ( + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func Versions() *schema.Table { + return &schema.Table{ + Name: "aws_elasticsearch_versions", + Description: `https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_ListVersions.html`, + Resolver: fetchElasticsearchVersions, + Multiplex: client.ServiceAccountRegionMultiplexer("es"), + Columns: []schema.Column{ + { + Name: "account_id", + Type: schema.TypeString, + Resolver: client.ResolveAWSAccount, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "region", + Type: schema.TypeString, + Resolver: client.ResolveAWSRegion, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "version", + Type: schema.TypeString, + Resolver: resolveVersion, + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "instance_types", + Type: schema.TypeJSON, + Resolver: resolveInstanceTypes, + }, + }, + } +} diff --git a/plugins/source/aws/resources/services/elasticsearch/versions_fetch.go b/plugins/source/aws/resources/services/elasticsearch/versions_fetch.go new file mode 100755 index 00000000000000..723c17c297afc3 --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/versions_fetch.go @@ -0,0 +1,54 @@ +package elasticsearch + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice/types" + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchElasticsearchVersions(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + svc := meta.(*client.Client).Services().Elasticsearchservice + + p := elasticsearchservice.NewListElasticsearchVersionsPaginator(svc, + &elasticsearchservice.ListElasticsearchVersionsInput{MaxResults: 100}, + ) + for p.HasMorePages() { + out, err := p.NextPage(ctx) + if err != nil { + return err + } + + res <- out.ElasticsearchVersions + } + + return nil +} + +func resolveVersion(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, c schema.Column) error { + return resource.Set(c.Name, resource.Item.(string)) +} + +func resolveInstanceTypes(ctx context.Context, meta schema.ClientMeta, resource *schema.Resource, c schema.Column) error { + svc := meta.(*client.Client).Services().Elasticsearchservice + + var instanceTypes []types.ESPartitionInstanceType + p := elasticsearchservice.NewListElasticsearchInstanceTypesPaginator(svc, + &elasticsearchservice.ListElasticsearchInstanceTypesInput{ + ElasticsearchVersion: aws.String(resource.Item.(string)), + }, + ) + for p.HasMorePages() { + out, err := p.NextPage(ctx) + if err != nil { + return err + } + + instanceTypes = append(instanceTypes, out.ElasticsearchInstanceTypes...) + } + + return resource.Set(c.Name, instanceTypes) +} diff --git a/plugins/source/aws/resources/services/elasticsearch/versions_mock_test.go b/plugins/source/aws/resources/services/elasticsearch/versions_mock_test.go new file mode 100644 index 00000000000000..bb75bfd998af9a --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/versions_mock_test.go @@ -0,0 +1,44 @@ +package elasticsearch + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice/types" + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/cloudquery/plugins/source/aws/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/golang/mock/gomock" +) + +func buildElasticSearchVersions(t *testing.T, ctrl *gomock.Controller) client.Services { + m := mocks.NewMockElasticsearchserviceClient(ctrl) + + var versions []string + if err := faker.FakeObject(&versions); err != nil { + t.Fatal(err) + } + m.EXPECT().ListElasticsearchVersions(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.ListElasticsearchVersionsOutput{ + ElasticsearchVersions: versions, + }, + nil, + ) + + var instanceTypes []types.ESPartitionInstanceType + if err := faker.FakeObject(&versions); err != nil { + t.Fatal(err) + } + m.EXPECT().ListElasticsearchInstanceTypes(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.ListElasticsearchInstanceTypesOutput{ + ElasticsearchInstanceTypes: instanceTypes, + }, + nil, + ) + + return client.Services{Elasticsearchservice: m} +} + +func TestElasticSearchVersions(t *testing.T) { + client.AwsMockTestHelper(t, Versions(), buildElasticSearchVersions, client.TestOptions{}) +} diff --git a/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints.go b/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints.go new file mode 100644 index 00000000000000..f8798e41105c79 --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints.go @@ -0,0 +1,62 @@ +// Code generated by codegen; DO NOT EDIT. + +package elasticsearch + +import ( + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func VpcEndpoints() *schema.Table { + return &schema.Table{ + Name: "aws_elasticsearch_vpc_endpoints", + Description: `https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_VpcEndpoint.html`, + Resolver: fetchElasticsearchVpcEndpoints, + Multiplex: client.ServiceAccountRegionMultiplexer("es"), + Columns: []schema.Column{ + { + Name: "account_id", + Type: schema.TypeString, + Resolver: client.ResolveAWSAccount, + }, + { + Name: "region", + Type: schema.TypeString, + Resolver: client.ResolveAWSRegion, + }, + { + Name: "domain_arn", + Type: schema.TypeString, + Resolver: schema.PathResolver("DomainArn"), + }, + { + Name: "endpoint", + Type: schema.TypeString, + Resolver: schema.PathResolver("Endpoint"), + }, + { + Name: "status", + Type: schema.TypeString, + Resolver: schema.PathResolver("Status"), + }, + { + Name: "id", + Type: schema.TypeString, + Resolver: schema.PathResolver("VpcEndpointId"), + CreationOptions: schema.ColumnCreationOptions{ + PrimaryKey: true, + }, + }, + { + Name: "vpc_endpoint_owner", + Type: schema.TypeString, + Resolver: schema.PathResolver("VpcEndpointOwner"), + }, + { + Name: "vpc_options", + Type: schema.TypeJSON, + Resolver: schema.PathResolver("VpcOptions"), + }, + }, + } +} diff --git a/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints_fetch.go b/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints_fetch.go new file mode 100755 index 00000000000000..62043f1967b567 --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints_fetch.go @@ -0,0 +1,55 @@ +package elasticsearch + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/plugin-sdk/schema" +) + +func fetchElasticsearchVpcEndpoints(ctx context.Context, meta schema.ClientMeta, parent *schema.Resource, res chan<- any) error { + svc := meta.(*client.Client).Services().Elasticsearchservice + + listInput := new(elasticsearchservice.ListVpcEndpointsInput) + var vpcEndpointIDs []string + // get the IDs first + for { + out, err := svc.ListVpcEndpoints(ctx, listInput) + if err != nil { + return err + } + + for _, summary := range out.VpcEndpointSummaryList { + vpcEndpointIDs = append(vpcEndpointIDs, *summary.VpcEndpointId) + } + + if out.NextToken == nil { + break + } + + listInput.NextToken = out.NextToken + } + + // slice in parts + const maxLen = 100 + for len(vpcEndpointIDs) > 0 { + var part []string + if len(vpcEndpointIDs) > maxLen { + part, vpcEndpointIDs = vpcEndpointIDs[:maxLen], vpcEndpointIDs[maxLen:] + } else { + part, vpcEndpointIDs = vpcEndpointIDs, nil + } + + out, err := svc.DescribeVpcEndpoints(ctx, + &elasticsearchservice.DescribeVpcEndpointsInput{VpcEndpointIds: part}, + ) + if err != nil { + return err + } + + res <- out.VpcEndpoints + } + + return nil +} diff --git a/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints_mock_test.go b/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints_mock_test.go new file mode 100644 index 00000000000000..420acbdc09336e --- /dev/null +++ b/plugins/source/aws/resources/services/elasticsearch/vpc_endpoints_mock_test.go @@ -0,0 +1,46 @@ +package elasticsearch + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice" + "github.com/aws/aws-sdk-go-v2/service/elasticsearchservice/types" + "github.com/cloudquery/cloudquery/plugins/source/aws/client" + "github.com/cloudquery/cloudquery/plugins/source/aws/client/mocks" + "github.com/cloudquery/plugin-sdk/faker" + "github.com/golang/mock/gomock" +) + +func buildElasticSearchVpcEndpoints(t *testing.T, ctrl *gomock.Controller) client.Services { + m := mocks.NewMockElasticsearchserviceClient(ctrl) + + var summary types.VpcEndpointSummary + if err := faker.FakeObject(&summary); err != nil { + t.Fatal(err) + } + m.EXPECT().ListVpcEndpoints(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.ListVpcEndpointsOutput{ + VpcEndpointSummaryList: []types.VpcEndpointSummary{summary}, + }, + nil, + ) + + var endpoint types.VpcEndpoint + if err := faker.FakeObject(&endpoint); err != nil { + t.Fatal(err) + } + endpoint.VpcEndpointId = summary.VpcEndpointId + + m.EXPECT().DescribeVpcEndpoints(gomock.Any(), gomock.Any()).Return( + &elasticsearchservice.DescribeVpcEndpointsOutput{ + VpcEndpoints: []types.VpcEndpoint{endpoint}, + }, + nil, + ) + + return client.Services{Elasticsearchservice: m} +} + +func TestElasticSearchVpcEndpoints(t *testing.T) { + client.AwsMockTestHelper(t, VpcEndpoints(), buildElasticSearchVpcEndpoints, client.TestOptions{}) +} diff --git a/website/pages/docs/plugins/sources/aws/tables.md b/website/pages/docs/plugins/sources/aws/tables.md index f275eb0f701ce9..8d1ea7eadcf3b4 100644 --- a/website/pages/docs/plugins/sources/aws/tables.md +++ b/website/pages/docs/plugins/sources/aws/tables.md @@ -195,6 +195,9 @@ - [aws_elasticbeanstalk_configuration_settings](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elasticbeanstalk_configuration_settings.md) - [aws_elasticbeanstalk_configuration_options](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elasticbeanstalk_configuration_options.md) - [aws_elasticsearch_domains](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elasticsearch_domains.md) +- [aws_elasticsearch_packages](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elasticsearch_packages.md) +- [aws_elasticsearch_versions](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elasticsearch_versions.md) +- [aws_elasticsearch_vpc_endpoints](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elasticsearch_vpc_endpoints.md) - [aws_elastictranscoder_pipelines](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elastictranscoder_pipelines.md) - [aws_elastictranscoder_pipeline_jobs](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elastictranscoder_pipeline_jobs.md) - [aws_elastictranscoder_presets](https://github.com/cloudquery/cloudquery/blob/main/plugins/source/aws/docs/tables/aws_elastictranscoder_presets.md)