Skip to content

Commit

Permalink
Add table azure_recovery_services_backup_job Closes #663 (#681)
Browse files Browse the repository at this point in the history
Co-authored-by: Madhushree Ray <[email protected]>
  • Loading branch information
ParthaI and madhushreeray30 authored Nov 2, 2023
1 parent 5d60a46 commit 2a80420
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 22 deletions.
1 change: 1 addition & 0 deletions azure/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"azure_private_dns_zone": tableAzurePrivateDNSZone(ctx),
"azure_provider": tableAzureProvider(ctx),
"azure_public_ip": tableAzurePublicIP(ctx),
"azure_recovery_services_backup_job": tableAzureRecoveryServicesBackupJob(ctx),
"azure_recovery_services_vault": tableAzureRecoveryServicesVault(ctx),
"azure_redis_cache": tableAzureRedisCache(ctx),
"azure_resource_group": tableAzureResourceGroup(ctx),
Expand Down
230 changes: 230 additions & 0 deletions azure/table_azure_recovery_services_backup_job.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
package azure

import (
"context"
"strings"

"github.com/Azure/azure-sdk-for-go/profiles/latest/recoveryservices/mgmt/recoveryservices"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/recoveryservices/armrecoveryservicesbackup/v3"
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
)

//// TABLE DEFINITION ////

func tableAzureRecoveryServicesBackupJob(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "azure_recovery_services_backup_job",
Description: "Azure Recovery Services Backup Job",
List: &plugin.ListConfig{
ParentHydrate: listRecoveryServicesVaults,
Hydrate: listRecoveryServicesBackupJobs,
IgnoreConfig: &plugin.IgnoreConfig{
ShouldIgnoreErrorFunc: isNotFoundError([]string{"ResourceNotFound", "404"}),
},
KeyColumns: plugin.KeyColumnSlice{
{
Name: "vault_name",
Require: plugin.Optional,
},
{
Name: "resource_group",
Require: plugin.Optional,
},
},
},
Columns: azureColumns([]*plugin.Column{
{
Name: "name",
Description: "Resource name associated with the resource.",
Type: proto.ColumnType_STRING,
},
{
Name: "vault_name",
Description: "The recovery vault name.",
Type: proto.ColumnType_STRING,
},
{
Name: "id",
Description: "Resource ID represents the complete path to the resource.",
Type: proto.ColumnType_STRING,
Transform: transform.FromGo(),
},
{
Name: "type",
Description: "Resource type represents the complete path of the form Namespace/ResourceType/ResourceType/...",
Type: proto.ColumnType_STRING,
},
{
Name: "etag",
Description: "Optional ETag.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ETag"),
},

// JSON fields
{
Name: "properties",
Description: "JobResource properties.",
Type: proto.ColumnType_JSON,
Transform: transform.From(backupJobProperties),
},

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

type JobInfo struct {
VaultName *string
ETag *string
Location *string
Properties armrecoveryservicesbackup.JobClassification
Tags map[string]*string
ID *string
Name *string
Type *string
}

//// LIST FUNCTION ////

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

cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
plugin.Logger(ctx).Error("azure_backup_job.listAzureBackupJobs", "NewDefaultAzureCredential", err)
return nil, err
}

vault := h.Item.(recoveryservices.Vault)

plugin.Logger(ctx).Error("Parameter ====>>", vault.Name, strings.Split(*vault.ID, "/")[4])

vaultName := d.EqualsQualString("vault_name")
rgName := d.EqualsQualString("resource_group")

if vaultName != "" {
if vaultName != *vault.Name {
return nil, nil
}
}

if rgName != "" {
if rgName != strings.Split(*vault.ID, "/")[4] {
return nil, nil
}
}

subscriptionID := session.SubscriptionID
clientFactory, err := armrecoveryservicesbackup.NewBackupJobsClient(subscriptionID, cred, nil)
if err != nil {
plugin.Logger(ctx).Error("azure_recovery_services_backup_job.listRecoveryServicesBackupJobs", "client_error", err)
return nil, nil
}
pager := clientFactory.NewListPager(*vault.Name, strings.Split(*vault.ID, "/")[4], &armrecoveryservicesbackup.BackupJobsClientListOptions{Filter: nil,
SkipToken: nil,
})
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
plugin.Logger(ctx).Error("azure_recovery_services_backup_job.listRecoveryServicesBackupJobs", "api_error", err)
return nil, nil
}

for _, v := range page.Value {
d.StreamListItem(ctx, JobInfo{
ETag: v.ETag,
Location: v.Location,
Properties: v.Properties,
Tags: v.Tags,
ID: v.ID,
Name: v.Name,
Type: v.Type,
VaultName: vault.Name,
})

// Check if context has been cancelled or if the limit has been hit (if specified)
// if there is a limit, it will return the number of rows required to reach this limit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
}

return nil, nil
}

//// TRANSFORM FUNCTION

func backupJobProperties(ctx context.Context, d *transform.TransformData) (interface{}, error) {
data := d.HydrateItem.(JobInfo)

output := make(map[string]interface{})

if data.Properties != nil {
if data.Properties.GetJob() != nil {
if data.Properties.GetJob().ActivityID != nil {
output["ActivityID"] = data.Properties.GetJob().ActivityID
}
if data.Properties.GetJob().BackupManagementType != nil {
output["BackupManagementType"] = data.Properties.GetJob().BackupManagementType
}
if data.Properties.GetJob().JobType != nil {
output["JobType"] = data.Properties.GetJob().JobType
}
if data.Properties.GetJob().EndTime != nil {
output["EndTime"] = data.Properties.GetJob().EndTime
}
if data.Properties.GetJob().EntityFriendlyName != nil {
output["EntityFriendlyName"] = data.Properties.GetJob().EntityFriendlyName
}
if data.Properties.GetJob().Operation != nil {
output["Operation"] = data.Properties.GetJob().Operation
}
if data.Properties.GetJob().StartTime != nil {
output["StartTime"] = data.Properties.GetJob().StartTime
}
if data.Properties.GetJob().Status != nil {
output["Status"] = data.Properties.GetJob().Status
}
}
}
return output, nil
}
38 changes: 38 additions & 0 deletions docs/tables/azure_recovery_services_backup_job.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Table: azure_recovery_services_backup_job

An Azure Backup job is a task that you can define and run to perform data protection operations on your Azure resources. These jobs are typically used to back up and restore data from various Azure services, such as virtual machines, databases, and files.

## Examples

### Basic info

```sql
select
name,
id,
type,
vault_name,
region
from
azure_recovery_services_backup_job
where
vault_name = 'my-vault';
```

### Get job properties of jobs

```sql
select
name,
id,
properties ->> 'JobType' as job_type,
properties ->> 'ActivityID' as activity_id,
properties ->> 'BackupManagementType' as backup_management_type,
properties ->> 'EndTime' as end_time,
properties ->> 'EntityFriendlyName' as entity_friendly_name,
properties ->> 'Operation' as Operation,
properties ->> 'StartTime' as start_time,
properties ->> 'Status' as Status
from
azure_recovery_services_backup_job;
```
16 changes: 11 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.21
require (
github.com/Azure/azure-sdk-for-go v58.0.0+incompatible
github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.0.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/recoveryservices/armrecoveryservicesbackup/v3 v3.0.0
github.com/Azure/azure-storage-blob-go v0.12.0
github.com/Azure/go-autorest/autorest v0.11.17
github.com/Azure/go-autorest/autorest/azure/auth v0.5.6
Expand All @@ -22,14 +23,16 @@ require (
cloud.google.com/go/iam v1.1.1 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.10 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.0 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/XiaoMi/pegasus-go-client v0.0.0-20210427083443-f3b6b08bc4c2 // indirect
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
github.com/agext/levenshtein v1.2.2 // indirect
Expand Down Expand Up @@ -58,6 +61,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
Expand All @@ -78,6 +82,7 @@ require (
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/klauspost/compress v1.15.11 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-ieproxy v0.0.1 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
Expand All @@ -90,6 +95,7 @@ require (
github.com/oklog/run v1.0.0 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pegasus-kv/thrift v0.13.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
Expand Down Expand Up @@ -117,13 +123,13 @@ require (
go.opentelemetry.io/otel/sdk/metric v0.40.0 // indirect
go.opentelemetry.io/otel/trace v1.17.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/oauth2 v0.10.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.126.0 // indirect
Expand Down
Loading

0 comments on commit 2a80420

Please sign in to comment.