github.com/opentofu/opentofu@v1.7.1/internal/command/providers_schema.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package command 7 8 import ( 9 "fmt" 10 "os" 11 12 "github.com/opentofu/opentofu/internal/backend" 13 "github.com/opentofu/opentofu/internal/command/arguments" 14 "github.com/opentofu/opentofu/internal/command/jsonprovider" 15 "github.com/opentofu/opentofu/internal/tfdiags" 16 ) 17 18 // ProvidersCommand is a Command implementation that prints out information 19 // about the providers used in the current configuration/state. 20 type ProvidersSchemaCommand struct { 21 Meta 22 } 23 24 func (c *ProvidersSchemaCommand) Help() string { 25 return providersSchemaCommandHelp 26 } 27 28 func (c *ProvidersSchemaCommand) Synopsis() string { 29 return "Show schemas for the providers used in the configuration" 30 } 31 32 func (c *ProvidersSchemaCommand) Run(args []string) int { 33 args = c.Meta.process(args) 34 cmdFlags := c.Meta.defaultFlagSet("providers schema") 35 var jsonOutput bool 36 cmdFlags.BoolVar(&jsonOutput, "json", false, "produce JSON output") 37 38 cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } 39 if err := cmdFlags.Parse(args); err != nil { 40 c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error())) 41 return 1 42 } 43 44 if !jsonOutput { 45 c.Ui.Error( 46 "The `tofu providers schema` command requires the `-json` flag.\n") 47 cmdFlags.Usage() 48 return 1 49 } 50 51 // Check for user-supplied plugin path 52 var err error 53 if c.pluginPath, err = c.loadPluginPath(); err != nil { 54 c.Ui.Error(fmt.Sprintf("Error loading plugin path: %s", err)) 55 return 1 56 } 57 58 var diags tfdiags.Diagnostics 59 60 enc, encDiags := c.Encryption() 61 diags = diags.Append(encDiags) 62 if encDiags.HasErrors() { 63 c.showDiagnostics(diags) 64 return 1 65 } 66 67 // Load the backend 68 b, backendDiags := c.Backend(nil, enc.State()) 69 diags = diags.Append(backendDiags) 70 if backendDiags.HasErrors() { 71 c.showDiagnostics(diags) 72 return 1 73 } 74 75 // We require a local backend 76 local, ok := b.(backend.Local) 77 if !ok { 78 c.showDiagnostics(diags) // in case of any warnings in here 79 c.Ui.Error(ErrUnsupportedLocalOp) 80 return 1 81 } 82 83 // This is a read-only command 84 c.ignoreRemoteVersionConflict(b) 85 86 // we expect that the config dir is the cwd 87 cwd, err := os.Getwd() 88 if err != nil { 89 c.Ui.Error(fmt.Sprintf("Error getting cwd: %s", err)) 90 return 1 91 } 92 93 // Build the operation 94 opReq := c.Operation(b, arguments.ViewJSON, enc) 95 opReq.ConfigDir = cwd 96 opReq.ConfigLoader, err = c.initConfigLoader() 97 opReq.AllowUnsetVariables = true 98 if err != nil { 99 diags = diags.Append(err) 100 c.showDiagnostics(diags) 101 return 1 102 } 103 104 // Get the context 105 lr, _, ctxDiags := local.LocalRun(opReq) 106 diags = diags.Append(ctxDiags) 107 if ctxDiags.HasErrors() { 108 c.showDiagnostics(diags) 109 return 1 110 } 111 112 schemas, moreDiags := lr.Core.Schemas(lr.Config, lr.InputState) 113 diags = diags.Append(moreDiags) 114 if moreDiags.HasErrors() { 115 c.showDiagnostics(diags) 116 return 1 117 } 118 119 jsonSchemas, err := jsonprovider.Marshal(schemas) 120 if err != nil { 121 c.Ui.Error(fmt.Sprintf("Failed to marshal provider schemas to json: %s", err)) 122 return 1 123 } 124 c.Ui.Output(string(jsonSchemas)) 125 126 return 0 127 } 128 129 const providersSchemaCommandHelp = ` 130 Usage: tofu [global options] providers schema -json 131 132 Prints out a json representation of the schemas for all providers used 133 in the current configuration. 134 `