Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add table azure_search_service closes #240 #257

Merged
merged 13 commits into from
Aug 12, 2021
Empty file.
14 changes: 14 additions & 0 deletions azure-test/tests/azure_search_service/test-get-expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"id": "{{ output.resource_id.value }}",
"name": "{{ resourceName }}",
"provisioning_state": "succeeded",
"region": "east us",
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
"resource_group": "{{ resourceName }}",
"sku_name": "standard",
"status": "running",
"subscription_id": "{{ output.subscription_id.value }}",
"tags_src": {},
"type": "Microsoft.Search/searchServices"
}
]
3 changes: 3 additions & 0 deletions azure-test/tests/azure_search_service/test-get-query.sql
Original file line number Diff line number Diff line change
@@ -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 }}';
10 changes: 10 additions & 0 deletions azure-test/tests/azure_search_service/test-hydrate-expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"name": "{{ resourceName }}",
"network_rule_set": {
"ipRules": []
},
"partition_count": 1,
"replica_count": 1
}
]
3 changes: 3 additions & 0 deletions azure-test/tests/azure_search_service/test-hydrate-query.sql
Original file line number Diff line number Diff line change
@@ -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 }}';
7 changes: 7 additions & 0 deletions azure-test/tests/azure_search_service/test-list-expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"id": "{{ output.resource_id.value }}",
"name": "{{ resourceName }}",
"region": "east us"
}
]
3 changes: 3 additions & 0 deletions azure-test/tests/azure_search_service/test-list-query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
select id, name, region
from azure.azure_search_service
where name = '{{ resourceName }}';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
null
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
select name, akas, title
from azure.azure_search_service
where name = 'dummy-{{ resourceName }}' and resource_group = '{{ resourceName }}';
10 changes: 10 additions & 0 deletions azure-test/tests/azure_search_service/test-turbot-expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"akas": [
"{{ output.resource_aka.value }}",
"{{ output.resource_aka_lower.value }}"
],
"name": "{{ resourceName }}",
"title": "{{ resourceName }}"
}
]
khushboo9024 marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions azure-test/tests/azure_search_service/test-turbot-query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
select name, akas, title
from azure.azure_search_service
where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}';
1 change: 1 addition & 0 deletions azure-test/tests/azure_search_service/variables.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
70 changes: 70 additions & 0 deletions azure-test/tests/azure_search_service/variables.tf
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions azure/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
222 changes: 222 additions & 0 deletions azure/table_azure_search_service.go
Original file line number Diff line number Diff line change
@@ -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: "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'.",
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
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'",
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
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.",
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
Transform: transform.FromField("ServiceProperties.StatusDetails"),
},
{
Name: "type",
Type: proto.ColumnType_STRING,
Description: "The type of the resource. E.g. 'Microsoft.Compute/virtualMachines' or 'Microsoft.Storage/storageAccounts'.",
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
},
{
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: "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"),
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
},
{
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: "tags_src",
Type: proto.ColumnType_JSON,
Description: "The resource tags.",
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
Transform: transform.FromField("Tags"),
},

// Azure standard columns
bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
{
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),
},
{
khushboo9024 marked this conversation as resolved.
Show resolved Hide resolved
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()

bigdatasourav marked this conversation as resolved.
Show resolved Hide resolved
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
}
Loading