mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-25 01:00:16 -05:00
Signed-off-by: AbstractionFactory <179820029+abstractionfactory@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
2a4d81042b
commit
60fdd359d5
@@ -0,0 +1 @@
|
||||
{"magic":"OpenTofu-External-Encryption-Method","version":1}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"payload": "base64-encoded payload to encrypt or decrypt",
|
||||
"key": "base64-encoded key for encryption or decryption (optional)"
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Header is the initial line that needs to be written as JSON when the program starts.
|
||||
type Header struct {
|
||||
Magic string `json:"magic"`
|
||||
Version int `json:"version"`
|
||||
}
|
||||
|
||||
// Input is the input data received from OpenTofu in response to the header as JSON.
|
||||
type Input struct {
|
||||
// Key is the encryption or decryption key, if present.
|
||||
Key []byte `json:"key,omitempty"`
|
||||
// Payload is the data to encrypt/decrypt.
|
||||
Payload []byte `json:"payload"`
|
||||
}
|
||||
|
||||
// Output is the data structure that should be written to the output.
|
||||
type Output struct {
|
||||
// Payload is the payload that has been encrypted/decrypted by the external method.
|
||||
Payload []byte `json:"payload"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Write logs to stderr
|
||||
log.Default().SetOutput(os.Stderr)
|
||||
|
||||
// Write header:
|
||||
header := Header{
|
||||
"OpenTofu-External-Encryption-Method",
|
||||
1,
|
||||
}
|
||||
marshalledHeader, err := json.Marshal(header)
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
}
|
||||
_, err = os.Stdout.Write(append(marshalledHeader, []byte("\n")...))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to write output: %v", err)
|
||||
}
|
||||
|
||||
// Read input:
|
||||
input, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read stdin: %v", err)
|
||||
}
|
||||
var inputData Input
|
||||
if err = json.Unmarshal(input, &inputData); err != nil {
|
||||
log.Fatalf("Failed to parse stdin: %v", err)
|
||||
}
|
||||
|
||||
// Encrypt/decrypt the input and produce the output here.
|
||||
var outputPayload []byte
|
||||
if len(os.Args) != 2 {
|
||||
log.Fatalf("Expected --encrypt or --decrypt")
|
||||
}
|
||||
switch os.Args[1] {
|
||||
case "--encrypt":
|
||||
// Encrypt the payload
|
||||
case "--decrypt":
|
||||
// Decrypt the payload
|
||||
default:
|
||||
log.Fatalf("Expected --encrypt or --decrypt")
|
||||
}
|
||||
|
||||
// Write output
|
||||
output := Output{
|
||||
Payload: outputPayload,
|
||||
}
|
||||
outputData, err := json.Marshal(output)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to stringify output: %v", err)
|
||||
}
|
||||
_, err = os.Stdout.Write(outputData)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to write output: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Make sure that this program isn't running interactively:
|
||||
if sys.stdout.isatty():
|
||||
sys.stderr.write("This is an OpenTofu encryption method and is not meant to be run interactively. "
|
||||
"Please configure this program in your OpenTofu encryption block to use it.\n")
|
||||
sys.exit(1)
|
||||
parser = argparse.ArgumentParser(prog='My External Encryption Method')
|
||||
parser.add_argument('--encrypt', action='store_true')
|
||||
parser.add_argument('--decrypt', action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Write the header:
|
||||
sys.stdout.write((json.dumps({"magic": "OpenTofu-External-Encryption-Method", "version": 1}) + "\n"))
|
||||
sys.stdout.flush()
|
||||
|
||||
# Read the input:
|
||||
inputData = sys.stdin.read()
|
||||
data = json.loads(inputData)
|
||||
|
||||
key = base64.b64decode(data["key"])
|
||||
payload = base64.b64decode(data["payload"])
|
||||
|
||||
# Produce the output payload here.
|
||||
if args.encrypt:
|
||||
outputPayload = b''
|
||||
elif args.decrypt:
|
||||
outputPayload = b''
|
||||
else:
|
||||
raise "Expected --encrypt or --decrypt."
|
||||
|
||||
# Write the output:
|
||||
sys.stdout.write(json.dumps({
|
||||
"payload": base64.b64encode(outputPayload).decode('ascii'),
|
||||
}))
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"payload": "base64-encoded encrypted or decrypted payload"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
encryption {
|
||||
key_provider "external" "foo" {
|
||||
encrypt_command = ["./some_program", "--encrypt"]
|
||||
decrypt_command = ["./some_program", "--decrypt"]
|
||||
# Optional:
|
||||
keys = key_provider.some.provider
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user