From 4a2773de1bb395f34901c8df87ee2be24bcf6d1d Mon Sep 17 00:00:00 2001 From: ParthaI Date: Wed, 11 Aug 2021 18:41:10 +0530 Subject: [PATCH 01/12] Add table azure_search_service closes #240 --- .../azure_search_service/dependencies.txt | 0 .../test-get-expected.json | 14 ++ .../azure_search_service/test-get-query.sql | 3 + .../test-hydrate-expected.json | 10 + .../test-hydrate-query.sql | 3 + .../test-list-expected.json | 7 + .../azure_search_service/test-list-query.sql | 3 + .../test-not-found-expected.json | 1 + .../test-not-found-query.sql | 3 + .../test-turbot-expected.json | 10 + .../test-turbot-query.sql | 3 + .../tests/azure_search_service/variables.json | 1 + .../tests/azure_search_service/variables.tf | 70 ++++++ azure/plugin.go | 1 + azure/table_azure_search_service.go | 222 ++++++++++++++++++ docs/tables/azure_search_service.md | 33 +++ 16 files changed, 384 insertions(+) create mode 100644 azure-test/tests/azure_search_service/dependencies.txt create mode 100644 azure-test/tests/azure_search_service/test-get-expected.json create mode 100644 azure-test/tests/azure_search_service/test-get-query.sql create mode 100644 azure-test/tests/azure_search_service/test-hydrate-expected.json create mode 100644 azure-test/tests/azure_search_service/test-hydrate-query.sql create mode 100644 azure-test/tests/azure_search_service/test-list-expected.json create mode 100644 azure-test/tests/azure_search_service/test-list-query.sql create mode 100644 azure-test/tests/azure_search_service/test-not-found-expected.json create mode 100644 azure-test/tests/azure_search_service/test-not-found-query.sql create mode 100644 azure-test/tests/azure_search_service/test-turbot-expected.json create mode 100644 azure-test/tests/azure_search_service/test-turbot-query.sql create mode 100644 azure-test/tests/azure_search_service/variables.json create mode 100644 azure-test/tests/azure_search_service/variables.tf create mode 100644 azure/table_azure_search_service.go create mode 100644 docs/tables/azure_search_service.md diff --git a/azure-test/tests/azure_search_service/dependencies.txt b/azure-test/tests/azure_search_service/dependencies.txt new file mode 100644 index 00000000..e69de29b diff --git a/azure-test/tests/azure_search_service/test-get-expected.json b/azure-test/tests/azure_search_service/test-get-expected.json new file mode 100644 index 00000000..23a0caf7 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-get-expected.json @@ -0,0 +1,14 @@ +[ + { + "id": "{{ output.resource_id.value }}", + "name": "{{ resourceName }}", + "provisioning_state": "succeeded", + "region": "east us", + "resource_group": "{{ resourceName }}", + "sku_name": "standard", + "status": "running", + "subscription_id": "{{ output.subscription_id.value }}", + "tags_src": {}, + "type": "Microsoft.Search/searchServices" + } +] \ No newline at end of file diff --git a/azure-test/tests/azure_search_service/test-get-query.sql b/azure-test/tests/azure_search_service/test-get-query.sql new file mode 100644 index 00000000..c2069681 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-get-query.sql @@ -0,0 +1,3 @@ +select name, id, type, status, provisioning_state, sku_name, tags_src, resource_group, region, subscription_id +from azure.azure_search_service +where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}'; diff --git a/azure-test/tests/azure_search_service/test-hydrate-expected.json b/azure-test/tests/azure_search_service/test-hydrate-expected.json new file mode 100644 index 00000000..0c243291 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-hydrate-expected.json @@ -0,0 +1,10 @@ +[ + { + "name": "{{ resourceName }}", + "network_rule_set": { + "ipRules": [] + }, + "partition_count": 1, + "replica_count": 1 + } +] \ No newline at end of file diff --git a/azure-test/tests/azure_search_service/test-hydrate-query.sql b/azure-test/tests/azure_search_service/test-hydrate-query.sql new file mode 100644 index 00000000..e3ac017b --- /dev/null +++ b/azure-test/tests/azure_search_service/test-hydrate-query.sql @@ -0,0 +1,3 @@ +select name, replica_count, partition_count, network_rule_set +from azure.azure_search_service +where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}'; \ No newline at end of file diff --git a/azure-test/tests/azure_search_service/test-list-expected.json b/azure-test/tests/azure_search_service/test-list-expected.json new file mode 100644 index 00000000..774ffe33 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-list-expected.json @@ -0,0 +1,7 @@ +[ + { + "id": "{{ output.resource_id.value }}", + "name": "{{ resourceName }}", + "region": "east us" + } +] diff --git a/azure-test/tests/azure_search_service/test-list-query.sql b/azure-test/tests/azure_search_service/test-list-query.sql new file mode 100644 index 00000000..a2444e07 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-list-query.sql @@ -0,0 +1,3 @@ +select id, name, region +from azure.azure_search_service +where name = '{{ resourceName }}'; diff --git a/azure-test/tests/azure_search_service/test-not-found-expected.json b/azure-test/tests/azure_search_service/test-not-found-expected.json new file mode 100644 index 00000000..19765bd5 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-not-found-expected.json @@ -0,0 +1 @@ +null diff --git a/azure-test/tests/azure_search_service/test-not-found-query.sql b/azure-test/tests/azure_search_service/test-not-found-query.sql new file mode 100644 index 00000000..fe460c4a --- /dev/null +++ b/azure-test/tests/azure_search_service/test-not-found-query.sql @@ -0,0 +1,3 @@ +select name, akas, title +from azure.azure_search_service +where name = 'dummy-{{ resourceName }}' and resource_group = '{{ resourceName }}'; diff --git a/azure-test/tests/azure_search_service/test-turbot-expected.json b/azure-test/tests/azure_search_service/test-turbot-expected.json new file mode 100644 index 00000000..b6e264d8 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-turbot-expected.json @@ -0,0 +1,10 @@ +[ + { + "akas": [ + "{{ output.resource_aka.value }}", + "{{ output.resource_aka_lower.value }}" + ], + "name": "{{ resourceName }}", + "title": "{{ resourceName }}" + } +] diff --git a/azure-test/tests/azure_search_service/test-turbot-query.sql b/azure-test/tests/azure_search_service/test-turbot-query.sql new file mode 100644 index 00000000..35f9b5d9 --- /dev/null +++ b/azure-test/tests/azure_search_service/test-turbot-query.sql @@ -0,0 +1,3 @@ +select name, akas, title +from azure.azure_search_service +where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}'; diff --git a/azure-test/tests/azure_search_service/variables.json b/azure-test/tests/azure_search_service/variables.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/azure-test/tests/azure_search_service/variables.json @@ -0,0 +1 @@ +{} diff --git a/azure-test/tests/azure_search_service/variables.tf b/azure-test/tests/azure_search_service/variables.tf new file mode 100644 index 00000000..0c0d8d74 --- /dev/null +++ b/azure-test/tests/azure_search_service/variables.tf @@ -0,0 +1,70 @@ + +variable "resource_name" { + type = string + default = "turbot-test-20200125-create-update" + description = "Name of the resource used throughout the test." +} + +variable "azure_environment" { + type = string + default = "public" + description = "Azure environment used for the test." +} + +variable "azure_subscription" { + type = string + default = "3510ae4d-530b-497d-8f30-53b9616fc6c1" + description = "Azure subscription used for the test." +} + +provider "azurerm" { + # Cannot be passed as a variable + version = "=2.50.0" + features {} + environment = var.azure_environment + subscription_id = var.azure_subscription +} + +data "azurerm_client_config" "current" {} + +data "null_data_source" "resource" { + inputs = { + scope = "azure:///subscriptions/${data.azurerm_client_config.current.subscription_id}" + } +} + +resource "azurerm_resource_group" "named_test_resource" { + name = var.resource_name + location = "East US" +} + +resource "azurerm_search_service" "named_test_resource" { + name = var.resource_name + resource_group_name = azurerm_resource_group.named_test_resource.name + location = azurerm_resource_group.named_test_resource.location + sku = "standard" +} + +output "resource_aka" { + value = "azure://${azurerm_search_service.named_test_resource.id}" +} + +output "resource_aka_lower" { + value = "azure://${lower(azurerm_search_service.named_test_resource.id)}" +} + +output "resource_name" { + value = var.resource_name +} + +output "resource_id" { + value = azurerm_search_service.named_test_resource.id +} + +output "location" { + value = lower(azurerm_search_service.named_test_resource.location) +} + +output "subscription_id" { + value = var.azure_subscription +} diff --git a/azure/plugin.go b/azure/plugin.go index 78e35882..fe43ca5f 100644 --- a/azure/plugin.go +++ b/azure/plugin.go @@ -88,6 +88,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "azure_role_assignment": tableAzureIamRoleAssignment(ctx), "azure_role_definition": tableAzureIamRoleDefinition(ctx), "azure_route_table": tableAzureRouteTable(ctx), + "azure_search_service": tableAzureSearchService(ctx), "azure_security_center_auto_provisioning": tableAzureSecurityCenterAutoProvisioning(ctx), "azure_security_center_contact": tableAzureSecurityCenterContact(ctx), "azure_security_center_jit_network_access_policy": tableAzureSecurityCenterJITNetworkAccessPolicy(ctx), diff --git a/azure/table_azure_search_service.go b/azure/table_azure_search_service.go new file mode 100644 index 00000000..10717ca4 --- /dev/null +++ b/azure/table_azure_search_service.go @@ -0,0 +1,222 @@ +package azure + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/services/search/mgmt/2020-08-01/search" + "github.com/turbot/steampipe-plugin-sdk/grpc/proto" + "github.com/turbot/steampipe-plugin-sdk/plugin" + "github.com/turbot/steampipe-plugin-sdk/plugin/transform" +) + +//// TABLE DEFINITION + +func tableAzureSearchService(_ context.Context) *plugin.Table { + return &plugin.Table{ + Name: "azure_search_service", + Description: "Azure Search Service", + Get: &plugin.GetConfig{ + KeyColumns: plugin.AllColumns([]string{"name", "resource_group"}), + Hydrate: getSearchService, + ShouldIgnoreError: isNotFoundError([]string{"ResourceNotFound", "ResourceGroupNotFound", "404"}), + }, + List: &plugin.ListConfig{ + Hydrate: listSearchServices, + }, + Columns: []*plugin.Column{ + { + Name: "name", + Type: proto.ColumnType_STRING, + Description: "The name of the resource.", + }, + { + Name: "id", + Type: proto.ColumnType_STRING, + Description: "Fully qualified resource ID for the resource.", + Transform: transform.FromGo(), + }, + { + Name: "type", + Type: proto.ColumnType_STRING, + Description: "The type of the resource. E.g. 'Microsoft.Compute/virtualMachines' or 'Microsoft.Storage/storageAccounts'.", + }, + { + Name: "provisioning_state", + Type: proto.ColumnType_STRING, + Description: "The state of the last provisioning operation performed on the search service. Provisioning is an intermediate state that occurs while service capacity is being established. After capacity is set up, provisioningState changes to either 'succeeded' or 'failed'. Client applications can poll provisioning status (the recommended polling interval is from 30 seconds to one minute) by using the Get Search Service operation to see when an operation is completed. If you are using the free service, this value tends to come back as 'succeeded' directly in the call to Create search service. This is because the free service uses capacity that is already set up. Possible values include: 'Succeeded', 'Provisioning', 'Failed'.", + Transform: transform.FromField("ServiceProperties.ProvisioningState"), + }, + { + Name: "status", + Type: proto.ColumnType_STRING, + Description: "The status of the search service. Possible values include: 'running': The search service is running and no provisioning operations are underway. 'provisioning': The search service is being provisioned or scaled up or down. 'deleting': The search service is being deleted. 'degraded': The search service is degraded. This can occur when the underlying search units are not healthy. The search service is most likely operational, but performance might be slow and some requests might be dropped. 'disabled': The search service is disabled. In this state, the service will reject all API requests. 'error': The search service is in an error state. If your service is in the degraded, disabled, or error states, it means the Azure Cognitive Search team is actively investigating the underlying issue. Dedicated services in these states are still chargeable based on the number of search units provisioned. Possible values include: 'ServiceStatusRunning', 'ServiceStatusProvisioning', 'ServiceStatusDeleting', 'ServiceStatusDegraded', 'ServiceStatusDisabled', 'ServiceStatusError'", + Transform: transform.FromField("ServiceProperties.Status"), + }, + { + Name: "status_details", + Type: proto.ColumnType_STRING, + Description: "The status of the search service. Possible values include: 'runniThe details of the search service status.", + Transform: transform.FromField("ServiceProperties.StatusDetails"), + }, + { + Name: "sku_name", + Type: proto.ColumnType_STRING, + Description: "The SKU of the Search Service, which determines price tier and capacity limits. This property is required when creating a new Search Service.", + Transform: transform.FromField("Sku.Name"), + }, + { + Name: "hosting_mode", + Type: proto.ColumnType_STRING, + Description: "Applicable only for the standard3 SKU. You can set this property to enable up to 3 high density partitions that allow up to 1000 indexes, which is much higher than the maximum indexes allowed for any other SKU. For the standard3 SKU, the value is either 'default' or 'highDensity'. For all other SKUs, this value must be 'default'. Possible values include: 'Default', 'HighDensity'.", + Transform: transform.FromField("ServiceProperties.HostingMode"), + }, + { + Name: "partition_count", + Type: proto.ColumnType_INT, + Description: "The number of partitions in the search service; if specified, it can be 1, 2, 3, 4, 6, or 12. Values greater than 1 are only valid for standard SKUs. For 'standard3' services with hostingMode set to 'highDensity', the allowed values are between 1 and 3.", + Transform: transform.FromField("ServiceProperties.PartitionCount"), + }, + { + Name: "public_network_access", + Type: proto.ColumnType_STRING, + Description: "This value can be set to 'enabled' to avoid breaking changes on existing customer resources and templates. If set to 'disabled', traffic over public interface is not allowed, and private endpoint connections would be the exclusive access method. Possible values include: 'Enabled', 'Disabled'.", + Transform: transform.FromField("ServiceProperties.PublicNetworkAccess"), + }, + { + Name: "replica_count", + Type: proto.ColumnType_INT, + Description: "The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU.", + Transform: transform.FromField("ServiceProperties.ReplicaCount"), + }, + { + Name: "network_rule_set", + Type: proto.ColumnType_JSON, + Description: "Network specific rules that determine how the Azure Cognitive Search service may be reached.", + Transform: transform.FromField("ServiceProperties.NetworkRuleSet"), + }, + { + Name: "private_endpoint_connections", + Type: proto.ColumnType_JSON, + Description: "The list of private endpoint connections to the Azure Cognitive Search service.", + Transform: transform.FromField("ServiceProperties.PrivateEndpointConnections"), + }, + { + Name: "shared_private_link_resources", + Type: proto.ColumnType_JSON, + Description: "The list of shared private link resources managed by the Azure Cognitive Search service.", + Transform: transform.FromField("ServiceProperties.SharedPrivateLinkResources"), + }, + { + Name: "identity", + Type: proto.ColumnType_JSON, + Description: "The identity of the resource.", + Transform: transform.FromField("Identity"), + }, + { + Name: "tags_src", + Type: proto.ColumnType_JSON, + Description: "The resource tags.", + Transform: transform.FromField("Tags"), + }, + + // Standard columns + { + Name: "title", + Description: ColumnDescriptionTitle, + Type: proto.ColumnType_STRING, + Transform: transform.FromField("Name"), + }, + { + Name: "tags", + Description: ColumnDescriptionTags, + Type: proto.ColumnType_JSON, + }, + { + Name: "akas", + Description: ColumnDescriptionAkas, + Type: proto.ColumnType_JSON, + Transform: transform.FromField("ID").Transform(idToAkas), + }, + { + Name: "region", + Description: ColumnDescriptionRegion, + Type: proto.ColumnType_STRING, + Transform: transform.FromField("Location").Transform(toLower), + }, + { + Name: "resource_group", + Description: ColumnDescriptionResourceGroup, + Type: proto.ColumnType_STRING, + Transform: transform.FromField("ID").Transform(extractResourceGroupFromID).Transform(toLower), + }, + { + Name: "subscription_id", + Description: ColumnDescriptionSubscription, + Type: proto.ColumnType_STRING, + Transform: transform.FromField("ID").Transform(idToSubscriptionID), + }, + }, + } +} + +//// LIST FUNCTION + +func listSearchServices(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { + session, err := GetNewSession(ctx, d, "MANAGEMENT") + if err != nil { + return nil, nil + } + subscriptionID := session.SubscriptionID + + searchClient := search.NewServicesClient(subscriptionID) + searchClient.Authorizer = session.Authorizer + + result, err := searchClient.ListBySubscription(ctx, nil) + if err != nil { + return nil, err + } + for _, service := range result.Values() { + d.StreamListItem(ctx, service) + } + + for result.NotDone() { + err = result.NextWithContext(ctx) + if err != nil { + return nil, err + } + for _, service := range result.Values() { + d.StreamListItem(ctx, service) + } + } + + return nil, err +} + +//// HYDRATE FUNCTIONS + +func getSearchService(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + plugin.Logger(ctx).Trace("getSearchService") + + name := d.KeyColumnQuals["name"].GetStringValue() + resourceGroup := d.KeyColumnQuals["resource_group"].GetStringValue() + + session, err := GetNewSession(ctx, d, "MANAGEMENT") + if err != nil { + return nil, err + } + subscriptionID := session.SubscriptionID + + searchClient := search.NewServicesClient(subscriptionID) + searchClient.Authorizer = session.Authorizer + + op, err := searchClient.Get(ctx, resourceGroup, name, nil) + if err != nil { + return nil, err + } + + if op.ID != nil { + return op, nil + } + + return nil, nil +} diff --git a/docs/tables/azure_search_service.md b/docs/tables/azure_search_service.md new file mode 100644 index 00000000..57bcdb05 --- /dev/null +++ b/docs/tables/azure_search_service.md @@ -0,0 +1,33 @@ +# Table: azure_search_service + +Azure Cognitive Search is the only cloud search service with built-in AI capabilities that enrich all types of information to help you identify and explore relevant content at scale. Use cognitive skills for vision, language and speech or use custom machine learning models to uncover insights from all types of content. + +## Examples + +### Basic info + +```sql +select + name, + id, + type, + provisioning_state, + status, + sku_name, + replica_count +from + azure_search_service; +``` + +### List virtual machine type search service + +```sql +select + name, + id, + type +from + azure_search_service +where + type = 'Microsoft.Compute/virtualMachines'; +``` From afa787dd9afdb1b76246b29cd6be2fbc801adee5 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Wed, 11 Aug 2021 18:55:15 +0530 Subject: [PATCH 02/12] Updated the column ordering --- azure/table_azure_search_service.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/azure/table_azure_search_service.go b/azure/table_azure_search_service.go index 10717ca4..0249817f 100644 --- a/azure/table_azure_search_service.go +++ b/azure/table_azure_search_service.go @@ -35,11 +35,6 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Description: "Fully qualified resource ID for the resource.", Transform: transform.FromGo(), }, - { - Name: "type", - Type: proto.ColumnType_STRING, - Description: "The type of the resource. E.g. 'Microsoft.Compute/virtualMachines' or 'Microsoft.Storage/storageAccounts'.", - }, { Name: "provisioning_state", Type: proto.ColumnType_STRING, @@ -59,10 +54,9 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Transform: transform.FromField("ServiceProperties.StatusDetails"), }, { - Name: "sku_name", + Name: "type", Type: proto.ColumnType_STRING, - Description: "The SKU of the Search Service, which determines price tier and capacity limits. This property is required when creating a new Search Service.", - Transform: transform.FromField("Sku.Name"), + Description: "The type of the resource. E.g. 'Microsoft.Compute/virtualMachines' or 'Microsoft.Storage/storageAccounts'.", }, { Name: "hosting_mode", @@ -88,6 +82,18 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Description: "The number of replicas in the search service. If specified, it must be a value between 1 and 12 inclusive for standard SKUs or between 1 and 3 inclusive for basic SKU.", Transform: transform.FromField("ServiceProperties.ReplicaCount"), }, + { + Name: "sku_name", + Type: proto.ColumnType_STRING, + Description: "The SKU of the Search Service, which determines price tier and capacity limits. This property is required when creating a new Search Service.", + Transform: transform.FromField("Sku.Name"), + }, + { + Name: "identity", + Type: proto.ColumnType_JSON, + Description: "The identity of the resource.", + Transform: transform.FromField("Identity"), + }, { Name: "network_rule_set", Type: proto.ColumnType_JSON, @@ -106,12 +112,6 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Description: "The list of shared private link resources managed by the Azure Cognitive Search service.", Transform: transform.FromField("ServiceProperties.SharedPrivateLinkResources"), }, - { - Name: "identity", - Type: proto.ColumnType_JSON, - Description: "The identity of the resource.", - Transform: transform.FromField("Identity"), - }, { Name: "tags_src", Type: proto.ColumnType_JSON, From 1055da2e91281645f828043ebb510fda8b6a702b Mon Sep 17 00:00:00 2001 From: ParthaI Date: Wed, 11 Aug 2021 19:06:16 +0530 Subject: [PATCH 03/12] Update --- azure/table_azure_search_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure/table_azure_search_service.go b/azure/table_azure_search_service.go index 0249817f..0b8b221b 100644 --- a/azure/table_azure_search_service.go +++ b/azure/table_azure_search_service.go @@ -119,7 +119,7 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Transform: transform.FromField("Tags"), }, - // Standard columns + // Azure standard columns { Name: "title", Description: ColumnDescriptionTitle, From ad4797b49b8d4be7367dee202cad63cd260c0f3c Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 12 Aug 2021 15:43:15 +0530 Subject: [PATCH 04/12] Added dignostic setting api call --- azure/table_azure_search_service.go | 65 ++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/azure/table_azure_search_service.go b/azure/table_azure_search_service.go index 0b8b221b..a96f12c5 100644 --- a/azure/table_azure_search_service.go +++ b/azure/table_azure_search_service.go @@ -3,6 +3,7 @@ package azure import ( "context" + "github.com/Azure/azure-sdk-for-go/profiles/2020-09-01/monitor/mgmt/insights" "github.com/Azure/azure-sdk-for-go/services/search/mgmt/2020-08-01/search" "github.com/turbot/steampipe-plugin-sdk/grpc/proto" "github.com/turbot/steampipe-plugin-sdk/plugin" @@ -38,19 +39,19 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { { Name: "provisioning_state", Type: proto.ColumnType_STRING, - Description: "The state of the last provisioning operation performed on the search service. Provisioning is an intermediate state that occurs while service capacity is being established. After capacity is set up, provisioningState changes to either 'succeeded' or 'failed'. Client applications can poll provisioning status (the recommended polling interval is from 30 seconds to one minute) by using the Get Search Service operation to see when an operation is completed. If you are using the free service, this value tends to come back as 'succeeded' directly in the call to Create search service. This is because the free service uses capacity that is already set up. Possible values include: 'Succeeded', 'Provisioning', 'Failed'.", + Description: "The state of the last provisioning operation performed on the search service.", Transform: transform.FromField("ServiceProperties.ProvisioningState"), }, { Name: "status", Type: proto.ColumnType_STRING, - Description: "The status of the search service. Possible values include: 'running': The search service is running and no provisioning operations are underway. 'provisioning': The search service is being provisioned or scaled up or down. 'deleting': The search service is being deleted. 'degraded': The search service is degraded. This can occur when the underlying search units are not healthy. The search service is most likely operational, but performance might be slow and some requests might be dropped. 'disabled': The search service is disabled. In this state, the service will reject all API requests. 'error': The search service is in an error state. If your service is in the degraded, disabled, or error states, it means the Azure Cognitive Search team is actively investigating the underlying issue. Dedicated services in these states are still chargeable based on the number of search units provisioned. Possible values include: 'ServiceStatusRunning', 'ServiceStatusProvisioning', 'ServiceStatusDeleting', 'ServiceStatusDegraded', 'ServiceStatusDisabled', 'ServiceStatusError'", + Description: "The status of the search service. Possible values include: 'running', deleting', 'provisioning', 'degraded', 'disabled', 'error' etc.", Transform: transform.FromField("ServiceProperties.Status"), }, { Name: "status_details", Type: proto.ColumnType_STRING, - Description: "The status of the search service. Possible values include: 'runniThe details of the search service status.", + Description: "The details of the search service status.", Transform: transform.FromField("ServiceProperties.StatusDetails"), }, { @@ -88,12 +89,19 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Description: "The SKU of the Search Service, which determines price tier and capacity limits. This property is required when creating a new Search Service.", Transform: transform.FromField("Sku.Name"), }, + { + Name: "diagnostic_settings", + Description: "A list of active diagnostic settings for the search service.", + Type: proto.ColumnType_JSON, + Hydrate: listSearchServiceDiagnosticSettings, + Transform: transform.FromValue(), + }, { Name: "identity", Type: proto.ColumnType_JSON, Description: "The identity of the resource.", Transform: transform.FromField("Identity"), - }, + }, { Name: "network_rule_set", Type: proto.ColumnType_JSON, @@ -119,7 +127,7 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Transform: transform.FromField("Tags"), }, - // Azure standard columns + // Steampipe standard columns { Name: "title", Description: ColumnDescriptionTitle, @@ -131,6 +139,8 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Description: ColumnDescriptionTags, Type: proto.ColumnType_JSON, }, + + // Azure standard columns { Name: "akas", Description: ColumnDescriptionAkas, @@ -200,6 +210,10 @@ func getSearchService(ctx context.Context, d *plugin.QueryData, h *plugin.Hydrat name := d.KeyColumnQuals["name"].GetStringValue() resourceGroup := d.KeyColumnQuals["resource_group"].GetStringValue() + if name == "" || resourceGroup == "" { + return nil, nil + } + session, err := GetNewSession(ctx, d, "MANAGEMENT") if err != nil { return nil, err @@ -220,3 +234,44 @@ func getSearchService(ctx context.Context, d *plugin.QueryData, h *plugin.Hydrat return nil, nil } + +func listSearchServiceDiagnosticSettings(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + plugin.Logger(ctx).Trace("listSearchServiceDiagnosticSettings") + id := h.Item.(search.Service).ID + + // Create session + session, err := GetNewSession(ctx, d, "MANAGEMENT") + if err != nil { + return nil, err + } + subscriptionID := session.SubscriptionID + + client := insights.NewDiagnosticSettingsClient(subscriptionID) + client.Authorizer = session.Authorizer + + op, err := client.List(ctx, *id) + if err != nil { + return nil, err + } + + // If we return the API response directly, the output only gives + // the contents of DiagnosticSettings + var diagnosticSettings []map[string]interface{} + for _, i := range *op.Value { + objectMap := make(map[string]interface{}) + if i.ID != nil { + objectMap["id"] = i.ID + } + if i.Name != nil { + objectMap["name"] = i.Name + } + if i.Type != nil { + objectMap["type"] = i.Type + } + if i.DiagnosticSettings != nil { + objectMap["properties"] = i.DiagnosticSettings + } + diagnosticSettings = append(diagnosticSettings, objectMap) + } + return diagnosticSettings, nil +} From e8759b140f476c7a1611277c433959f65298e736 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 12 Aug 2021 15:46:00 +0530 Subject: [PATCH 05/12] Update --- azure/table_azure_search_service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure/table_azure_search_service.go b/azure/table_azure_search_service.go index a96f12c5..bc34708c 100644 --- a/azure/table_azure_search_service.go +++ b/azure/table_azure_search_service.go @@ -139,14 +139,14 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Description: ColumnDescriptionTags, Type: proto.ColumnType_JSON, }, - - // Azure standard columns { Name: "akas", Description: ColumnDescriptionAkas, Type: proto.ColumnType_JSON, Transform: transform.FromField("ID").Transform(idToAkas), }, + + // Azure standard columns { Name: "region", Description: ColumnDescriptionRegion, From 879a6d5e601f11422b15903aa5d6cfa731660e3d Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 12 Aug 2021 16:36:03 +0530 Subject: [PATCH 06/12] Update the table column description --- azure/table_azure_search_service.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/azure/table_azure_search_service.go b/azure/table_azure_search_service.go index bc34708c..adf2b39f 100644 --- a/azure/table_azure_search_service.go +++ b/azure/table_azure_search_service.go @@ -86,7 +86,7 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { { Name: "sku_name", Type: proto.ColumnType_STRING, - Description: "The SKU of the Search Service, which determines price tier and capacity limits. This property is required when creating a new Search Service.", + Description: "The SKU of the Search Service, which determines price tier and capacity limits. This property is required when creating a new search service.", Transform: transform.FromField("Sku.Name"), }, { @@ -105,19 +105,19 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { { Name: "network_rule_set", Type: proto.ColumnType_JSON, - Description: "Network specific rules that determine how the Azure Cognitive Search service may be reached.", + Description: "Network specific rules that determine how the azure cognitive search service may be reached.", Transform: transform.FromField("ServiceProperties.NetworkRuleSet"), }, { Name: "private_endpoint_connections", Type: proto.ColumnType_JSON, - Description: "The list of private endpoint connections to the Azure Cognitive Search service.", + Description: "The list of private endpoint connections to the azure cognitive search service.", Transform: transform.FromField("ServiceProperties.PrivateEndpointConnections"), }, { Name: "shared_private_link_resources", Type: proto.ColumnType_JSON, - Description: "The list of shared private link resources managed by the Azure Cognitive Search service.", + Description: "The list of shared private link resources managed by the azure cognitive search service.", Transform: transform.FromField("ServiceProperties.SharedPrivateLinkResources"), }, { From 5f3a73d51cb0086f5e18c4c9e693dd31747e6e30 Mon Sep 17 00:00:00 2001 From: Khushboo Date: Thu, 12 Aug 2021 16:55:57 +0530 Subject: [PATCH 07/12] fixed indentation --- .../azure_search_service/test-get-expected.json | 2 +- .../test-hydrate-expected.json | 2 +- .../azure_search_service/test-list-expected.json | 10 +++++----- .../test-turbot-expected.json | 16 ++++++++-------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/azure-test/tests/azure_search_service/test-get-expected.json b/azure-test/tests/azure_search_service/test-get-expected.json index 23a0caf7..79284ed4 100644 --- a/azure-test/tests/azure_search_service/test-get-expected.json +++ b/azure-test/tests/azure_search_service/test-get-expected.json @@ -11,4 +11,4 @@ "tags_src": {}, "type": "Microsoft.Search/searchServices" } -] \ No newline at end of file +] diff --git a/azure-test/tests/azure_search_service/test-hydrate-expected.json b/azure-test/tests/azure_search_service/test-hydrate-expected.json index 0c243291..d09fa3df 100644 --- a/azure-test/tests/azure_search_service/test-hydrate-expected.json +++ b/azure-test/tests/azure_search_service/test-hydrate-expected.json @@ -7,4 +7,4 @@ "partition_count": 1, "replica_count": 1 } -] \ No newline at end of file +] diff --git a/azure-test/tests/azure_search_service/test-list-expected.json b/azure-test/tests/azure_search_service/test-list-expected.json index 774ffe33..7d108981 100644 --- a/azure-test/tests/azure_search_service/test-list-expected.json +++ b/azure-test/tests/azure_search_service/test-list-expected.json @@ -1,7 +1,7 @@ [ - { - "id": "{{ output.resource_id.value }}", - "name": "{{ resourceName }}", - "region": "east us" - } + { + "id": "{{ output.resource_id.value }}", + "name": "{{ resourceName }}", + "region": "east us" + } ] diff --git a/azure-test/tests/azure_search_service/test-turbot-expected.json b/azure-test/tests/azure_search_service/test-turbot-expected.json index b6e264d8..02cd3c76 100644 --- a/azure-test/tests/azure_search_service/test-turbot-expected.json +++ b/azure-test/tests/azure_search_service/test-turbot-expected.json @@ -1,10 +1,10 @@ [ - { - "akas": [ - "{{ output.resource_aka.value }}", - "{{ output.resource_aka_lower.value }}" - ], - "name": "{{ resourceName }}", - "title": "{{ resourceName }}" - } + { + "akas": [ + "{{ output.resource_aka.value }}", + "{{ output.resource_aka_lower.value }}" + ], + "name": "{{ resourceName }}", + "title": "{{ resourceName }}" + } ] From 49a67d851932e6a218b094596400995ae419cfaf Mon Sep 17 00:00:00 2001 From: Khushboo Date: Thu, 12 Aug 2021 17:07:21 +0530 Subject: [PATCH 08/12] updated the documentation --- docs/tables/azure_search_service.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tables/azure_search_service.md b/docs/tables/azure_search_service.md index 57bcdb05..16453f6f 100644 --- a/docs/tables/azure_search_service.md +++ b/docs/tables/azure_search_service.md @@ -19,15 +19,15 @@ from azure_search_service; ``` -### List virtual machine type search service +### List publicly accessible search services ```sql select name, id, - type + public_network_access from azure_search_service where - type = 'Microsoft.Compute/virtualMachines'; -``` + public_network_access = 'Enabled'; +``` \ No newline at end of file From 6d9c0921309923ef0775a744638de52617c171a9 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 12 Aug 2021 17:46:21 +0530 Subject: [PATCH 09/12] Removed the hard coded value and tags_src column --- .../tests/azure_search_service/test-get-expected.json | 3 +-- azure-test/tests/azure_search_service/test-get-query.sql | 2 +- azure/table_azure_search_service.go | 9 +-------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/azure-test/tests/azure_search_service/test-get-expected.json b/azure-test/tests/azure_search_service/test-get-expected.json index 23a0caf7..969f3c11 100644 --- a/azure-test/tests/azure_search_service/test-get-expected.json +++ b/azure-test/tests/azure_search_service/test-get-expected.json @@ -3,12 +3,11 @@ "id": "{{ output.resource_id.value }}", "name": "{{ resourceName }}", "provisioning_state": "succeeded", - "region": "east us", + "region": "{{ output.location.value }}", "resource_group": "{{ resourceName }}", "sku_name": "standard", "status": "running", "subscription_id": "{{ output.subscription_id.value }}", - "tags_src": {}, "type": "Microsoft.Search/searchServices" } ] \ No newline at end of file diff --git a/azure-test/tests/azure_search_service/test-get-query.sql b/azure-test/tests/azure_search_service/test-get-query.sql index c2069681..666def8f 100644 --- a/azure-test/tests/azure_search_service/test-get-query.sql +++ b/azure-test/tests/azure_search_service/test-get-query.sql @@ -1,3 +1,3 @@ -select name, id, type, status, provisioning_state, sku_name, tags_src, resource_group, region, subscription_id +select name, id, type, status, provisioning_state, sku_name, resource_group, region, subscription_id from azure.azure_search_service where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}'; diff --git a/azure/table_azure_search_service.go b/azure/table_azure_search_service.go index adf2b39f..9667b38a 100644 --- a/azure/table_azure_search_service.go +++ b/azure/table_azure_search_service.go @@ -57,7 +57,7 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { { Name: "type", Type: proto.ColumnType_STRING, - Description: "The type of the resource. E.g. 'Microsoft.Compute/virtualMachines' or 'Microsoft.Storage/storageAccounts'.", + Description: "The type of the resource.", }, { Name: "hosting_mode", @@ -100,7 +100,6 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Name: "identity", Type: proto.ColumnType_JSON, Description: "The identity of the resource.", - Transform: transform.FromField("Identity"), }, { Name: "network_rule_set", @@ -120,12 +119,6 @@ func tableAzureSearchService(_ context.Context) *plugin.Table { Description: "The list of shared private link resources managed by the azure cognitive search service.", Transform: transform.FromField("ServiceProperties.SharedPrivateLinkResources"), }, - { - Name: "tags_src", - Type: proto.ColumnType_JSON, - Description: "The resource tags.", - Transform: transform.FromField("Tags"), - }, // Steampipe standard columns { From a1a2269630123429244ef9b823927f456cef7d3d Mon Sep 17 00:00:00 2001 From: bigdatasourav Date: Thu, 12 Aug 2021 18:04:49 +0530 Subject: [PATCH 10/12] refactor --- .../tests/azure_search_service/test-hydrate-expected.json | 3 --- azure-test/tests/azure_search_service/test-hydrate-query.sql | 2 +- azure-test/tests/azure_search_service/test-list-expected.json | 2 +- azure-test/tests/azure_search_service/variables.tf | 1 - 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/azure-test/tests/azure_search_service/test-hydrate-expected.json b/azure-test/tests/azure_search_service/test-hydrate-expected.json index d09fa3df..2581c5bb 100644 --- a/azure-test/tests/azure_search_service/test-hydrate-expected.json +++ b/azure-test/tests/azure_search_service/test-hydrate-expected.json @@ -1,9 +1,6 @@ [ { "name": "{{ resourceName }}", - "network_rule_set": { - "ipRules": [] - }, "partition_count": 1, "replica_count": 1 } diff --git a/azure-test/tests/azure_search_service/test-hydrate-query.sql b/azure-test/tests/azure_search_service/test-hydrate-query.sql index e3ac017b..5224d3b5 100644 --- a/azure-test/tests/azure_search_service/test-hydrate-query.sql +++ b/azure-test/tests/azure_search_service/test-hydrate-query.sql @@ -1,3 +1,3 @@ -select name, replica_count, partition_count, network_rule_set +select name, replica_count, partition_count from azure.azure_search_service where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}'; \ No newline at end of file diff --git a/azure-test/tests/azure_search_service/test-list-expected.json b/azure-test/tests/azure_search_service/test-list-expected.json index 7d108981..da0ead62 100644 --- a/azure-test/tests/azure_search_service/test-list-expected.json +++ b/azure-test/tests/azure_search_service/test-list-expected.json @@ -2,6 +2,6 @@ { "id": "{{ output.resource_id.value }}", "name": "{{ resourceName }}", - "region": "east us" + "region": "{{ output.location.value }}" } ] diff --git a/azure-test/tests/azure_search_service/variables.tf b/azure-test/tests/azure_search_service/variables.tf index 0c0d8d74..f84fa594 100644 --- a/azure-test/tests/azure_search_service/variables.tf +++ b/azure-test/tests/azure_search_service/variables.tf @@ -1,4 +1,3 @@ - variable "resource_name" { type = string default = "turbot-test-20200125-create-update" From ac5086d410d8ecc38475921fb9faedc43ace8c51 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 12 Aug 2021 18:30:46 +0530 Subject: [PATCH 11/12] Updated the region in get query --- azure-test/tests/azure_search_service/test-get-expected.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-test/tests/azure_search_service/test-get-expected.json b/azure-test/tests/azure_search_service/test-get-expected.json index d1ba694d..210210f2 100644 --- a/azure-test/tests/azure_search_service/test-get-expected.json +++ b/azure-test/tests/azure_search_service/test-get-expected.json @@ -3,7 +3,7 @@ "id": "{{ output.resource_id.value }}", "name": "{{ resourceName }}", "provisioning_state": "succeeded", - "region": "{{ output.location.value }}", + "region": "east us", "resource_group": "{{ resourceName }}", "sku_name": "standard", "status": "running", From 82db1ad92e9c617b281c5d502d8f2b6289aef588 Mon Sep 17 00:00:00 2001 From: ParthaI Date: Thu, 12 Aug 2021 18:34:10 +0530 Subject: [PATCH 12/12] update --- azure-test/tests/azure_search_service/test-list-expected.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-test/tests/azure_search_service/test-list-expected.json b/azure-test/tests/azure_search_service/test-list-expected.json index da0ead62..7d108981 100644 --- a/azure-test/tests/azure_search_service/test-list-expected.json +++ b/azure-test/tests/azure_search_service/test-list-expected.json @@ -2,6 +2,6 @@ { "id": "{{ output.resource_id.value }}", "name": "{{ resourceName }}", - "region": "{{ output.location.value }}" + "region": "east us" } ]