Skip to content

Commit

Permalink
Resource with exactly one match will be filled in by default
Browse files Browse the repository at this point in the history
The resource IDs which has exactly one recommendation will now be
automatically filled in by the TF resource type on the first launch. The
line is prefixed by 💡 as an indicator. The following edits on such
lines will clear that 💡.
  • Loading branch information
magodo committed Jan 28, 2022
1 parent cf31dd4 commit 39e953a
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 6 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ aztfy [option] <resource group name>

The tool will list all the resources resides in the specified resource group.

For each resource, `aztfy` will ask the user to input the Terraform resource type for each Azure resource (e.g. `azurerm_linux_virtual_machine`). Users can press `r` to see the possible resource type for the selected import item, though this is not guaranteed to be 100% accurate.
For each resource, `aztfy` will ask the user to input the Terraform resource type for each Azure resource (e.g. `azurerm_linux_virtual_machine`). Users can press `r` to see the possible resource type for the selected import item, though this is not guaranteed to be 100% accurate. In case there is exactly one resource type match for the import item, that resource type will be automatically be filled in the text input for the users, with a 💡 line prefix as an indication.

In some cases, there are Azure resources that have no corresponding Terraform resource (e.g. due to lacks of Terraform support), or some resource might be created as a side effect of provisioning another resource (e.g. the Disk resource is created automatically when provisioning a VM). In these cases, you can skip these resources without typing anything.

After getting the input from user, `aztfy` will run `terraform import` under the hood to import each resource. Then it will run `terraform add -from-state` to generate the Terraform template for each imported resource. Whereas there are kinds of [limitations](https://github.com/apparentlymart/terrafy/blob/main/docs/quirks.md) causing the output of `terraform add` to be an invalid Terraform template in most cases. `aztfy` will leverage extra knowledge from the provider (which is generated from the provider codebase) to further manipulate the template, to make it pass the Terraform validations against the provider.
After going through all the resources to be imported, users press `w` to proceed.`aztfy` will run `terraform import` under the hood to import each resource. Then it will run `terraform add -from-state` to generate the Terraform template for each imported resource. Whereas there are kinds of [limitations](https://github.com/apparentlymart/terrafy/blob/main/docs/quirks.md) causing the output of `terraform add` to be an invalid Terraform template in most cases. `aztfy` will leverage extra knowledge from the provider (which is generated from the provider codebase) to further manipulate the template, to make it pass the Terraform validations against the provider.

As the last step, `aztfy` will leverage the ARM template to inject dependencies between each resource. This makes the generated Terraform template to be useful.

Expand Down
8 changes: 7 additions & 1 deletion internal/meta/importlist.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package meta

// TFResourceTypeSkip is a special resource type which represents to skip this resource from importing.
const TFResourceTypeSkip string = "Skip"

type ImportItem struct {
// The azure resource id
ResourceID string
Expand All @@ -18,10 +21,13 @@ type ImportItem struct {

// The terraform resource name
TFResourceName string

// Whether this TF resource type is from recommendation
IsRecommended bool
}

func (item ImportItem) Skip() bool {
return item.TFResourceType == ""
return item.TFResourceType == TFResourceTypeSkip
}

func (item *ImportItem) TFAddr() string {
Expand Down
1 change: 1 addition & 0 deletions internal/ui/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
const ErrorEmoji = "❗️"
const WarningEmoji = "❓"
const OKEmoji = "✅"
const BulbEmoji = "💡"

// Colors for dark and light backgrounds.
var (
Expand Down
11 changes: 11 additions & 0 deletions internal/ui/importlist/importlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ func NewModel(c meta.Meta, l meta.ImportList, idx int) Model {
for idx, item := range l {
ti := textinput.NewModel()
ti.SetCursorMode(textinput.CursorStatic)

// This only happens on the first time to new the model, where each resource's TFResourceType is empty.
// Later iterations, this is either a concret resource type or the TFResourceTypeSkip.
// For this first iteration, we try to give it a recommendation resource type if there is an exact match, otherwise, set it to TFResourceTypeSkip.
if item.TFResourceType == "" {
item.TFResourceType = meta.TFResourceTypeSkip
if len(recommendations[idx]) == 1 {
item.IsRecommended = true
item.TFResourceType = recommendations[idx][0]
}
}
if !item.Skip() {
ti.SetValue(item.TFResourceType)
}
Expand Down
10 changes: 10 additions & 0 deletions internal/ui/importlist/importlist_delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"strings"

"github.com/Azure/aztfy/internal/meta"
"github.com/Azure/aztfy/internal/ui/aztfyclient"
"github.com/Azure/aztfy/internal/ui/common"
"github.com/Azure/aztfy/schema"
Expand Down Expand Up @@ -47,6 +48,9 @@ func NewImportItemDelegate() list.ItemDelegate {
selItem.v.Imported = false
}

// Clear the is recommended flag that were set.
selItem.v.IsRecommended = false

// "Enter" focus current selected item
setListKeyMapEnabled(m, false)
cmd := selItem.textinput.Focus()
Expand Down Expand Up @@ -75,6 +79,12 @@ func NewImportItemDelegate() list.ItemDelegate {
selItem.v.ValidateError = err
return
}

// Reset to TFResourceTypeSkip if value is empty
if rt == "" {
rt = meta.TFResourceTypeSkip
}

selItem.v.TFResourceType = rt
return
}
Expand Down
8 changes: 5 additions & 3 deletions internal/ui/importlist/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ func (i Item) Title() string {
case i.v.Imported:
return common.OKEmoji + i.v.ResourceID
default:
if i.v.IsRecommended {
return common.BulbEmoji + i.v.ResourceID
}
return i.v.ResourceID
}
}
Expand All @@ -29,11 +32,10 @@ func (i Item) Description() string {
if i.textinput.Focused() {
return i.textinput.View()
}
v := i.textinput.Value()
if v == "" {
if i.v.Skip() {
return "(Skip)"
}
return v
return i.textinput.Value()
}

func (i Item) FilterValue() string { return i.v.ResourceID }

0 comments on commit 39e953a

Please sign in to comment.