]>
Commit | Line | Data |
---|---|---|
bae9f6d2 JC |
1 | package terraform |
2 | ||
3 | import ( | |
107c1cdb ND |
4 | "github.com/hashicorp/terraform/addrs" |
5 | "github.com/hashicorp/terraform/configs" | |
6 | "github.com/hashicorp/terraform/states" | |
7 | "github.com/hashicorp/terraform/tfdiags" | |
bae9f6d2 JC |
8 | ) |
9 | ||
10 | // ImportOpts are used as the configuration for Import. | |
11 | type ImportOpts struct { | |
12 | // Targets are the targets to import | |
13 | Targets []*ImportTarget | |
14 | ||
107c1cdb ND |
15 | // Config is optional, and specifies a config tree that will be loaded |
16 | // into the graph and evaluated. This is the source for provider | |
17 | // configurations. | |
18 | Config *configs.Config | |
bae9f6d2 JC |
19 | } |
20 | ||
21 | // ImportTarget is a single resource to import. | |
22 | type ImportTarget struct { | |
107c1cdb ND |
23 | // Addr is the address for the resource instance that the new object should |
24 | // be imported into. | |
25 | Addr addrs.AbsResourceInstance | |
bae9f6d2 JC |
26 | |
27 | // ID is the ID of the resource to import. This is resource-specific. | |
28 | ID string | |
29 | ||
107c1cdb ND |
30 | // ProviderAddr is the address of the provider that should handle the import. |
31 | ProviderAddr addrs.AbsProviderConfig | |
bae9f6d2 JC |
32 | } |
33 | ||
34 | // Import takes already-created external resources and brings them | |
35 | // under Terraform management. Import requires the exact type, name, and ID | |
36 | // of the resources to import. | |
37 | // | |
38 | // This operation is idempotent. If the requested resource is already | |
39 | // imported, no changes are made to the state. | |
40 | // | |
41 | // Further, this operation also gracefully handles partial state. If during | |
42 | // an import there is a failure, all previously imported resources remain | |
43 | // imported. | |
107c1cdb ND |
44 | func (c *Context) Import(opts *ImportOpts) (*states.State, tfdiags.Diagnostics) { |
45 | var diags tfdiags.Diagnostics | |
46 | ||
bae9f6d2 JC |
47 | // Hold a lock since we can modify our own state here |
48 | defer c.acquireRun("import")() | |
49 | ||
50 | // Copy our own state | |
51 | c.state = c.state.DeepCopy() | |
52 | ||
53 | // If no module is given, default to the module configured with | |
54 | // the Context. | |
107c1cdb ND |
55 | config := opts.Config |
56 | if config == nil { | |
57 | config = c.config | |
bae9f6d2 JC |
58 | } |
59 | ||
60 | // Initialize our graph builder | |
61 | builder := &ImportGraphBuilder{ | |
62 | ImportTargets: opts.Targets, | |
107c1cdb ND |
63 | Config: config, |
64 | Components: c.components, | |
65 | Schemas: c.schemas, | |
bae9f6d2 JC |
66 | } |
67 | ||
68 | // Build the graph! | |
107c1cdb ND |
69 | graph, graphDiags := builder.Build(addrs.RootModuleInstance) |
70 | diags = diags.Append(graphDiags) | |
71 | if graphDiags.HasErrors() { | |
72 | return c.state, diags | |
bae9f6d2 JC |
73 | } |
74 | ||
75 | // Walk it | |
107c1cdb ND |
76 | _, walkDiags := c.walk(graph, walkImport) |
77 | diags = diags.Append(walkDiags) | |
78 | if walkDiags.HasErrors() { | |
79 | return c.state, diags | |
bae9f6d2 JC |
80 | } |
81 | ||
107c1cdb | 82 | return c.state, diags |
bae9f6d2 | 83 | } |