Skip to content

Commit

Permalink
add azapi support
Browse files Browse the repository at this point in the history
  • Loading branch information
wuxu92 committed Oct 17, 2023
1 parent eb789a4 commit 7f6ee0b
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 150 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.vscode
dist/
.idea
aztfexport
53 changes: 53 additions & 0 deletions flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package main

import (
"fmt"
"os/exec"
"strings"

"github.com/Azure/aztfexport/pkg/config"
"github.com/hashicorp/go-hclog"
"github.com/magodo/terraform-client-go/tfclient"
"github.com/urfave/cli/v2"
)

Expand All @@ -18,6 +22,7 @@ type FlagSet struct {
flagAppend bool
flagDevProvider bool
flagProviderVersion string
flagProviderName string
flagBackendType string
flagBackendConfig cli.StringSlice
flagFullConfig bool
Expand Down Expand Up @@ -172,3 +177,51 @@ func (flag FlagSet) DescribeCLI(mode string) string {
}
return "aztfexport " + strings.Join(args, " ")
}

func (f FlagSet) BuildCommonConfig() (config.CommonConfig, error) {
cred, clientOpt, err := buildAzureSDKCredAndClientOpt(f)
if err != nil {
return config.CommonConfig{}, err
}

cfg := config.CommonConfig{
SubscriptionId: f.flagSubscriptionId,
AzureSDKCredential: cred,
AzureSDKClientOption: *clientOpt,
OutputDir: f.flagOutputDir,
ProviderVersion: f.flagProviderVersion,
ProviderName: f.flagProviderName,
DevProvider: f.flagDevProvider,
ContinueOnError: f.flagContinue,
BackendType: f.flagBackendType,
BackendConfig: f.flagBackendConfig.Value(),
FullConfig: f.flagFullConfig,
Parallelism: f.flagParallelism,
HCLOnly: f.flagHCLOnly,
ModulePath: f.flagModulePath,
TelemetryClient: initTelemetryClient(f.flagSubscriptionId),
}

if f.flagAppend {
cfg.OutputFileNames = config.OutputFileNames{
TerraformFileName: "terraform.aztfexport.tf",
ProviderFileName: "provider.aztfexport.tf",
MainFileName: "main.aztfexport.tf",
ImportBlockFileName: "import.aztfexport.tf",
}
}

if f.hflagTFClientPluginPath != "" {
// #nosec G204
tfc, err := tfclient.New(tfclient.Option{
Cmd: exec.Command(flagset.hflagTFClientPluginPath),
Logger: hclog.NewNullLogger(),
})
if err != nil {
return cfg, err
}
cfg.TFClient = tfc
}

return cfg, nil
}
51 changes: 51 additions & 0 deletions internal/meta/base_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"path/filepath"
"strings"

"github.com/Azure/aztfexport/internal/resourceset"
"github.com/hashicorp/go-version"
tfjson "github.com/hashicorp/terraform-json"

Expand Down Expand Up @@ -84,6 +85,7 @@ type baseMeta struct {
resourceClient *armresources.Client
providerVersion string
devProvider bool
providerName string
backendType string
backendConfig []string
providerConfig map[string]cty.Value
Expand Down Expand Up @@ -204,6 +206,7 @@ func NewBaseMeta(cfg config.CommonConfig) (*baseMeta, error) {
backendType: cfg.BackendType,
backendConfig: cfg.BackendConfig,
providerConfig: cfg.ProviderConfig,
providerName: cfg.ProviderName,
fullConfig: cfg.FullConfig,
parallelism: cfg.Parallelism,
hclOnly: cfg.HCLOnly,
Expand Down Expand Up @@ -257,6 +260,8 @@ func (meta *baseMeta) CleanTFState(ctx context.Context, addr string) {
func (meta *baseMeta) ParallelImport(ctx context.Context, items []*ImportItem) error {
meta.tc.Trace(telemetry.Info, "ParallelImport Enter")
defer meta.tc.Trace(telemetry.Info, "ParallelImport Leave")
// return nil

itemsCh := make(chan *ImportItem, len(items))
for _, item := range items {
itemsCh <- item
Expand Down Expand Up @@ -512,11 +517,30 @@ func (meta baseMeta) generateCfg(ctx context.Context, l ImportList, cfgTrans ...
return meta.generateConfig(cfginfos)
}

func (meta *baseMeta) useAzAPI() bool {
return meta.providerName == "azapi"
}

func (meta *baseMeta) buildTerraformConfigForImportDir() string {
if meta.devProvider {
return "terraform {}"
}

if meta.useAzAPI() {
return fmt.Sprintf(`terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "%s"
}
azapi = {
source = "azure/azapi"
}
}
}
`, meta.providerVersion)
}

return fmt.Sprintf(`terraform {
required_providers {
azurerm = {
Expand All @@ -536,6 +560,22 @@ func (meta *baseMeta) buildTerraformConfig(backendType string) string {
`, backendType)
}

if meta.useAzAPI() {
return fmt.Sprintf(`terraform {
backend %q {}
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "%s"
}
azapi = {
source = "azure/azapi"
}
}
}
`, backendType, meta.providerVersion)
}

return fmt.Sprintf(`terraform {
backend %q {}
required_providers {
Expand All @@ -555,6 +595,10 @@ func (meta *baseMeta) buildProviderConfig() string {
for k, v := range meta.providerConfig {
body.SetAttributeValue(k, v)
}

if meta.useAzAPI() {
_ = f.Body().AppendNewBlock("provider", []string{"azapi"}).Body()
}
return string(f.Bytes())
}

Expand Down Expand Up @@ -1030,6 +1074,13 @@ func (meta *baseMeta) deinit_tf(ctx context.Context) error {
return nil
}

func (meta *baseMeta) GenTFResources(set *resourceset.AzureResourceSet) []resourceset.TFResource {
if meta.useAzAPI() {
return set.ToAzAPIResources()
}
return set.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
}

func getModuleDir(modulePaths []string, moduleDir string) (string, error) {
// Ensure the module path is something called by the main module
// We are following the module source and recursively call the LoadModule below. This is valid since we only support local path modules.
Expand Down
13 changes: 9 additions & 4 deletions internal/meta/config_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/hcl/v2/hclwrite"
"github.com/magodo/armid"
"github.com/zclconf/go-cty/cty"
)

Expand Down Expand Up @@ -141,9 +142,9 @@ func (cfgs ConfigInfos) addReferenceDependency() error {
// TF resource id to Azure resource ids.
// Typically, one TF resource id maps to one Azure resource id. However, there are cases that one one TF resource id maps to multiple Azure resource ids.
// E.g. A parent and child resources have the same TF id. Or the association resource's TF id is the same as the master resource's.
m := map[string][]string{}
m := map[string][]armid.ResourceId{}
for _, cfg := range cfgs {
m[cfg.TFResourceId] = append(m[cfg.TFResourceId], cfg.AzureResourceID.String())
m[cfg.TFResourceId] = append(m[cfg.TFResourceId], cfg.AzureResourceID)
}

for i, cfg := range cfgs {
Expand All @@ -170,10 +171,14 @@ func (cfgs ConfigInfos) addReferenceDependency() error {

var dependingResourceIdsWithoutSelf []string
for _, id := range dependingResourceIds[:] {
if id == cfg.AzureResourceID.String() {
if id.String() == cfg.AzureResourceID.String() {
continue
}
dependingResourceIdsWithoutSelf = append(dependingResourceIdsWithoutSelf, id)
// if cfg is parent of `id` resource, we should skip, or it will cause circular dependency, so skip parent depends on sub resources
if cfg.AzureResourceID.Equal(id.Parent()) {
continue
}
dependingResourceIdsWithoutSelf = append(dependingResourceIdsWithoutSelf, id.String())
}
if len(dependingResourceIdsWithoutSelf) != 0 {
cfg.DependsOn = append(cfg.DependsOn, Dependency{Candidates: dependingResourceIdsWithoutSelf})
Expand Down
3 changes: 2 additions & 1 deletion internal/meta/meta_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ func (meta *MetaQuery) ListResource(ctx context.Context) (ImportList, error) {
}

log.Printf("[DEBUG] Azure Resource set map to TF resource set")
rl := rset.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
// rl := rset.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
rl := meta.GenTFResources(rset)

var l ImportList
for i, res := range rl {
Expand Down
6 changes: 3 additions & 3 deletions internal/meta/meta_res.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ func (meta MetaResource) ScopeName() string {
}

func (meta *MetaResource) ListResource(_ context.Context) (ImportList, error) {
resourceSet := resourceset.AzureResourceSet{
resourceSet := &resourceset.AzureResourceSet{
Resources: []resourceset.AzureResource{
{
Id: meta.AzureId,
},
},
}
log.Printf("[DEBUG] Azure Resource set map to TF resource set")
rl := resourceSet.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
rl := meta.GenTFResources(resourceSet)

// This is to record known resource types. In case there is a known resource type and there comes another same typed resource,
// then we need to modify the resource name. Otherwise, there will be a resource address conflict.
Expand All @@ -67,7 +67,7 @@ func (meta *MetaResource) ListResource(_ context.Context) (ImportList, error) {
name += fmt.Sprintf("-%d", rtCnt[res.TFType]-1)
}
tfAddr := tfaddr.TFAddr{
Type: res.TFType, //this might be empty if have multiple matches in aztft
Type: res.TFType, // this might be empty if have multiple matches in aztft
Name: name,
}
item := ImportItem{
Expand Down
2 changes: 1 addition & 1 deletion internal/meta/meta_rg.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (meta *MetaResourceGroup) ListResource(ctx context.Context) (ImportList, er
}

log.Printf("[DEBUG] Azure Resource set map to TF resource set")
rl := rset.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
rl := meta.GenTFResources(rset)

var l ImportList
for i, res := range rl {
Expand Down
11 changes: 11 additions & 0 deletions internal/resourceset/azure_resource_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,14 @@ func (rset AzureResourceSet) ToTFResources(parallelism int, cred azcore.TokenCre

return tfresources
}

func (rset AzureResourceSet) ToAzAPIResources() (result []TFResource) {
for _, res := range rset.Resources {
result = append(result, TFResource{
AzureId: res.Id,
TFId: res.Id.String(),
TFType: "azapi_resource",
})
}
return
}
Loading

0 comments on commit 7f6ee0b

Please sign in to comment.