diff --git a/flag.go b/flag.go index eafca16..4a17f8c 100644 --- a/flag.go +++ b/flag.go @@ -82,8 +82,10 @@ type FlagSet struct { // flagResName (for single resource) // flagResType (for single resource) // flagPattern (for multi resources) + // flagRecursive // flagIncludeRoleAssignment // flagIncludeManagedResource + // flagIncludeResourceGroup // // rg: // flagPattern @@ -239,38 +241,26 @@ func (flag FlagSet) DescribeCLI(mode Mode) string { if flag.flagIncludeManagedResource { args = append(args, "--include-managed-resource=true") } - - switch mode { - case ModeResource: - if flag.flagResName != "" { - args = append(args, "--name="+flag.flagResName) - } - if flag.flagResType != "" { - args = append(args, "--type="+flag.flagResType) - } - if flag.flagPattern != "" { - args = append(args, "--name-pattern="+flag.flagPattern) - } - case ModeResourceGroup: - if flag.flagPattern != "" { - args = append(args, "--name-pattern="+flag.flagPattern) - } - case ModeQuery: - if flag.flagPattern != "" { - args = append(args, "--name-pattern="+flag.flagPattern) - } - if flag.flagRecursive { - args = append(args, "--recursive=true") - } - if flag.flagIncludeResourceGroup { - args = append(args, "--include-resource-group=true") - } - if flag.flagARGTable != "" { - args = append(args, "--arg-table="+flag.flagARGTable) - } - if flag.flagARGAuthorizationScopeFilter != "" { - args = append(args, "--arg-authorization-scope-filter="+flag.flagARGAuthorizationScopeFilter) - } + if flag.flagIncludeResourceGroup { + args = append(args, "--include-resource-group=true") + } + if flag.flagResName != "" { + args = append(args, "--name="+flag.flagResName) + } + if flag.flagResType != "" { + args = append(args, "--type="+flag.flagResType) + } + if flag.flagPattern != "" { + args = append(args, "--name-pattern="+flag.flagPattern) + } + if flag.flagRecursive { + args = append(args, "--recursive=true") + } + if flag.flagARGTable != "" { + args = append(args, "--arg-table="+flag.flagARGTable) + } + if flag.flagARGAuthorizationScopeFilter != "" { + args = append(args, "--arg-authorization-scope-filter="+flag.flagARGAuthorizationScopeFilter) } return "aztfexport " + strings.Join(args, " ") } diff --git a/internal/meta/meta_res.go b/internal/meta/meta_res.go index 1799e08..2bbc4d9 100644 --- a/internal/meta/meta_res.go +++ b/internal/meta/meta_res.go @@ -21,6 +21,8 @@ type MetaResource struct { resourceNameSuffix string includeRoleAssignment bool includeManagedResource bool + includeResourceGroup bool + recursive bool } func NewMetaResource(cfg config.Config) (*MetaResource, error) { @@ -45,8 +47,10 @@ func NewMetaResource(cfg config.Config) (*MetaResource, error) { AzureIds: ids, ResourceName: cfg.TFResourceName, ResourceType: cfg.TFResourceType, + recursive: cfg.RecursiveQuery, includeRoleAssignment: cfg.IncludeRoleAssignment, includeManagedResource: cfg.IncludeManagedResource, + includeResourceGroup: cfg.IncludeResourceGroup, } meta.resourceNamePrefix, meta.resourceNameSuffix = resourceNamePattern(cfg.ResourceNamePattern) @@ -68,12 +72,9 @@ func (meta *MetaResource) ListResource(ctx context.Context) (ImportList, error) rl = append(rl, resourceset.AzureResource{Id: id}) } - if meta.includeRoleAssignment { - var err error - rl, err = meta.listByIds(ctx, rl) - if err != nil { - return nil, fmt.Errorf("querying extension resources: %v", err) - } + rl, err := meta.listByIds(ctx, rl) + if err != nil { + return nil, fmt.Errorf("querying extension resources: %v", err) } meta.Logger().Debug("Azure Resource set map to TF resource set") @@ -186,6 +187,8 @@ func (meta MetaResource) listByIds(ctx context.Context, resources []resourceset. Parallelism: meta.parallelism, ExtensionResourceTypes: extBuilder{includeRoleAssignment: meta.includeRoleAssignment}.Build(), IncludeManaged: meta.includeManagedResource, + IncludeResourceGroup: meta.includeResourceGroup, + Recursive: meta.recursive, } lister, err := azlist.NewLister(opt) diff --git a/main.go b/main.go index e40d7ed..82ead37 100644 --- a/main.go +++ b/main.go @@ -424,6 +424,19 @@ func main() { Value: "res-", Destination: &flagset.flagPattern, }, + &cli.BoolFlag{ + Name: "recursive", + EnvVars: []string{"AZTFEXPORT_RECURSIVE"}, + Aliases: []string{"r"}, + Usage: "Recursively lists child resources of the resulting query resources", + Destination: &flagset.flagRecursive, + }, + &cli.BoolFlag{ + Name: "include-resource-group", + EnvVars: []string{"AZTFEXPORT_INCLUDE_RESOURCE_GROUP"}, + Usage: "Include the resource groups that the exported resources belong to", + Destination: &flagset.flagIncludeResourceGroup, + }, }, commonFlags...) resourceGroupFlags := append([]cli.Flag{ @@ -438,6 +451,14 @@ func main() { }, commonFlags...) queryFlags := append([]cli.Flag{ + &cli.StringFlag{ + Name: "name-pattern", + EnvVars: []string{"AZTFEXPORT_NAME_PATTERN"}, + Aliases: []string{"p"}, + Usage: `The pattern of the resource name. The semantic of a pattern is the same as Go's os.CreateTemp()`, + Value: "res-", + Destination: &flagset.flagPattern, + }, &cli.BoolFlag{ Name: "recursive", EnvVars: []string{"AZTFEXPORT_RECURSIVE"}, @@ -463,7 +484,7 @@ func main() { Usage: `The Azure Resource Graph Authorization Scope Filter parameter. Possible values are: "AtScopeAndBelow", "AtScopeAndAbove", "AtScopeAboveAndBelow" and "AtScopeExact"`, Destination: &flagset.flagARGAuthorizationScopeFilter, }, - }, resourceGroupFlags...) + }, commonFlags...) mappingFileFlags := append([]cli.Flag{}, commonFlags...) @@ -588,6 +609,8 @@ func main() { TFResourceName: flagset.flagResName, TFResourceType: flagset.flagResType, ResourceNamePattern: flagset.flagPattern, + RecursiveQuery: flagset.flagRecursive, + IncludeResourceGroup: flagset.flagIncludeResourceGroup, IncludeRoleAssignment: flagset.flagIncludeRoleAssignment, IncludeManagedResource: flagset.flagIncludeManagedResource, } diff --git a/pkg/config/config.go b/pkg/config/config.go index dfb2b19..b51d4e6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -116,18 +116,18 @@ type Config struct { // MappingFile specifies the path of mapping file, this indicates the map file mode. MappingFile string - // IncludeRoleAssignment specifies whether to include the role assignments assigned to the exported resources - IncludeRoleAssignment bool - - // IncludeManagedResource specifies Whether to include internal resources managed by Azure in the exported configuration - IncludeManagedResource bool - ///////////////////////// // Scope: rg, res (multi), query // ResourceNamePattern specifies the resource name pattern ResourceNamePattern string + // IncludeRoleAssignment specifies whether to include the role assignments assigned to the exported resources + IncludeRoleAssignment bool + + // IncludeManagedResource specifies whether to allow service team/3rd party managed resources to be exported + IncludeManagedResource bool + ///////////////////////// // Scope: res (single) @@ -137,12 +137,17 @@ type Config struct { TFResourceType string ///////////////////////// - // Scope: query + // Scope: res, query - // RecursiveQuery specifies whether to recursively list the child/proxy resources of the ARG resulted resource list + // RecursiveQuery specifies whether to recursively list the child/proxy resources of the ARG resulted or user specified resource list RecursiveQuery bool + // IncludeResourceGroup specifies whether to include the resource groups that the exported resources belong to IncludeResourceGroup bool + + ///////////////////////// + // Scope: query + // ARGTable specifies the ARG table name, which defaults to the "Resources" table ARGTable string // ARGAuthorizationScopeFilter specifies the AuthorizationScopeFilter parameter. Possible values are: "AtScopeAndBelow", "AtScopeAndAbove", "AtScopeAboveAndBelow" and "AtScopeExact"