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_express_route_circuit. Closes #153 #170

Merged
merged 8 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"id": "{{ output.resource_id.value }}",
"name": "{{ resourceName }}",
"resource_group": "{{ resourceName }}",
"sku_tier": "{{ output.sku_tire.value }}"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
select name, id, sku_tier, resource_group
from azure.azure_express_route_circuit
where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}';
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"akas": [
"{{ output.resource_aka.value }}",
"{{ output.resource_aka_lower.value }}"
],
"name": "{{ resourceName }}",
"sku_name": "{{ output.sku_tire.value }}_{{ output.sku_family.value }}",
"sku_tier": "{{ output.sku_tire.value }}",
"tags": {
"Name": "{{ resourceName }}"
},
"title": "{{ resourceName }}"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
select name, sku_name, sku_tier, akas, tags, title
from azure.azure_express_route_circuit
where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"id": "{{ output.resource_id.value }}",
"name": "{{ resourceName }}"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
select id, name
from azure.azure_express_route_circuit
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, tags, title
from azure.azure_express_route_circuit
where name = 'dummy-{{ resourceName }}' and resource_group = '{{ resourceName }}';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"akas": [
"{{ output.resource_aka.value }}",
"{{ output.resource_aka_lower.value }}"
],
"name": "{{ resourceName }}",
"tags": {
"Name": "{{ resourceName }}"
},
"title": "{{ resourceName }}"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
select name, akas, title, tags
from azure.azure_express_route_circuit
where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
84 changes: 84 additions & 0 deletions azure-test/tests/azure_express_route_circuit/varibles.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
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.43.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 = "West US"
}

resource "azurerm_express_route_circuit" "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
service_provider_name = "Equinix"
peering_location = "Silicon Valley"
bandwidth_in_mbps = 50

sku {
tier = "Standard"
family = "MeteredData"
}

tags = {
Name = var.resource_name
}
}

output "resource_aka" {
value = "azure://${azurerm_express_route_circuit.named_test_resource.id}"
}

output "resource_aka_lower" {
value = "azure://${lower(azurerm_express_route_circuit.named_test_resource.id)}"
}

output "sku_tire" {
value = "Standard"
}

output "sku_family" {
value = "MeteredData"
}

output "resource_name" {
value = var.resource_name
}

output "resource_id" {
value = azurerm_express_route_circuit.named_test_resource.id
}

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 @@ -42,6 +42,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"azure_cosmosdb_mongo_database": tableAzureCosmosDBMongoDatabase(ctx),
"azure_cosmosdb_sql_database": tableAzureCosmosDBSQLDatabase(ctx),
"azure_diagnostic_setting": tableAzureDiagnosticSetting(ctx),
"azure_express_route_circuit": tableAzureExpressRouteCircuit(ctx),
"azure_firewall": tableAzureFirewall(ctx),
"azure_key_vault": tableAzureKeyVault(ctx),
"azure_key_vault_key": tableAzureKeyVaultKey(ctx),
Expand Down
230 changes: 230 additions & 0 deletions azure/table_azure_express_route_circuit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
package azure

import (
"context"

"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2020-07-01/network"
"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 tableAzureExpressRouteCircuit(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "azure_expressroute_circuit",
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
Description: "Azure Express Route Circuit",
Get: &plugin.GetConfig{
KeyColumns: plugin.AllColumns([]string{"name", "resource_group"}),
Hydrate: getExpressRouteCircuit,
ShouldIgnoreError: isNotFoundError([]string{"ResourceNotFound", "ResourceGroupNotFound", "404"}),
},
List: &plugin.ListConfig{
Hydrate: listExpressRouteCircuits,
},
Columns: []*plugin.Column{
{
Name: "name",
Description: "The friendly name that identifies the Circuit.",
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
Type: proto.ColumnType_STRING,
},
{
Name: "id",
Description: "Resource ID.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ID"),
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
},
{
Name: "etag",
Description: "A unique read-only string that changes whenever the resource is updated.",
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
Type: proto.ColumnType_STRING,
},
{
Name: "sku_name",
Description: "The name of the SKU.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Sku.Name"),
},
{
Name: "sku_tier",
Description: "The tier of the SKU. Possible values include: 'ExpressRouteCircuitSkuTierStandard', 'ExpressRouteCircuitSkuTierPremium', 'ExpressRouteCircuitSkuTierBasic', 'ExpressRouteCircuitSkuTierLocal'.",
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Sku.Tier"),
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
},
{
Name: "sku_family",
Description: "Family - The family of the SKU. Possible values include: 'UnlimitedData', 'MeteredData'.",
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Sku.Family"),
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
},
{
Name: "allow_classic_operations",
Description: "Allow classic operations.",
Type: proto.ColumnType_BOOL,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.AllowClassicOperations"),
},
{
Name: "circuit_provisioning_state",
Description: "The CircuitProvisioningState state of the resource.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.CircuitProvisioningState"),
},
{
Name: "service_provider_provisioning_state",
Description: "The ServiceProviderProvisioningState state of the resource. Possible values include: 'ServiceProviderProvisioningStateNotProvisioned', 'ServiceProviderProvisioningStateProvisioning', 'ServiceProviderProvisioningStateProvisioned', 'ServiceProviderProvisioningStateDeprovisioning.",
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.ServiceProviderProvisioningState"),
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
},
{
Name: "authorizations",
Description: "The list of authorizations.",
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.Authorizations"),
},
{
Name: "peerings",
Description: "The list of peerings.",
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.Peerings"),
},
{
Name: "service_key",
Description: "The ServiceKey.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.ServiceKey"),
},
{
Name: "service_provider_notes",
Description: "The ServiceProviderNotes.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.ServiceProviderNotes"),
},
{
Name: "service_provider_properties",
Description: "The ServiceProviderProperties.",
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.ServiceProviderProperties"),
},
{
Name: "express_route_port",
Description: "The reference to the ExpressRoutePort resource when the circuit is provisioned on an ExpressRoutePort resource.",
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.ExpressRoutePort"),
},
{
Name: "bandwidth_in_gbps",
Description: "The bandwidth of the circuit when the circuit is provisioned on an ExpressRoutePort resource.",
Type: proto.ColumnType_DOUBLE,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.BandwidthInGbps"),
},
{
Name: "provisioning_state",
Description: "The provisioning state of the express route circuit resource. Possible values include: 'Succeeded', 'Updating', 'Deleting', 'Failed'.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.ProvisioningState"),
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved
},
{
Name: "global_reach_enabled",
Description: "Flag denoting global reach status.",
Type: proto.ColumnType_BOOL,
Transform: transform.FromField("ExpressRouteCircuitPropertiesFormat.GlobalReachEnabled"),
},

// Steampipe 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),
},

// Azure standard columns
{
ParthaI 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),
},
{
Name: "subscription_id",
Description: ColumnDescriptionSubscription,
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ID").Transform(idToSubscriptionID),
},
},
}
}

//// LIST FUNCTION

func listExpressRouteCircuits(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
session, err := GetNewSession(ctx, d, "MANAGEMENT")
if err != nil {
return nil, err
}
subscriptionID := session.SubscriptionID

expressRouteCircuitClient := network.NewExpressRouteCircuitsClient(subscriptionID)
ParthaI marked this conversation as resolved.
Show resolved Hide resolved
expressRouteCircuitClient.Authorizer = session.Authorizer

pagesLeft := true
for pagesLeft {
result, err := expressRouteCircuitClient.ListAll(ctx)
if err != nil {
return nil, err
}

for _, routeCircuit := range result.Values() {
d.StreamListItem(ctx, routeCircuit)
}
result.NextWithContext(context.Background())
pagesLeft = result.NotDone()
}

return nil, nil
}

//// HYDRATE FUNCTION
Subhajit97 marked this conversation as resolved.
Show resolved Hide resolved

func getExpressRouteCircuit(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
name := d.KeyColumnQuals["name"].GetStringValue()
resourceGroup := d.KeyColumnQuals["resource_group"].GetStringValue()

ParthaI marked this conversation as resolved.
Show resolved Hide resolved
// Handle empty name or resourceGroup
if name == "" || resourceGroup == "" {
return nil, nil
}

session, err := GetNewSession(ctx, d, "MANAGEMENT")
if err != nil {
return nil, err
}
subscriptionID := session.SubscriptionID

expressRouteCircuitClient := network.NewExpressRouteCircuitsClient(subscriptionID)
ParthaI marked this conversation as resolved.
Show resolved Hide resolved
expressRouteCircuitClient.Authorizer = session.Authorizer

op, err := expressRouteCircuitClient.Get(ctx, resourceGroup, name)
ParthaI marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
return op, nil
}
Loading