-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
- block stream encryption + remove non-stream endpoint - Nothing uses the feature yet. ``` ❯ kubectl exec -it -n flux-system chart-tofu-controller-648fbc54f8-7sprc -- ls -la /blob-cache/ total 12 drwxrwsrwx 2 root 1337 4096 Dec 19 15:29 . drwxr-xr-x 1 root root 4096 Dec 19 15:29 .. -rw-r--r-- 1 controll 1337 800 Dec 20 09:41 terraform-helloworld-tf-priv.tar.gz ❯ kubectl exec -it -n flux-system chart-tofu-controller-648fbc54f8-7sprc -- hexdump -C /blob-cache/terraform-helloworld-tf-priv.tar.gz | head -n 3 00000000 1b 3f 00 8d 25 67 17 79 87 04 d7 b9 03 f2 6c ba |.?..%g.y......l.| 00000010 bc 0c 7e 75 29 de 25 1f bb 99 c4 49 2d 99 1b e0 |..~u).%....I-...| 00000020 b3 72 2f ca ab fb 5f 93 ee b4 ba bd a6 76 83 38 |.r/..._......v.8| ``` with a small go temp app, after decryption and untar (the repo itself has only one file: `main.tf`): ``` ❯ kubectl cp -n flux-system chart-tofu-controller-648fbc54f8-7sprc:/blob-cache/terraform-helloworld-tf-priv.tar.gz ./terraform-helloworld-tf-priv.tar.gz tar: removing leading '/' from member names ❯ go run . INFO[0000] /tmp/1417200660 ❯ tree /tmp/1417200660 /tmp/1417200660 ├── backend_override.tf ├── generated.auto.tfvars.json └── main.tf 1 directory, 3 files ``` Extra To Do items: - Add feature flag Signed-off-by: Balazs Nadasdi <[email protected]> Signed-off-by: Victoria Nadasdi <[email protected]>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package controllers | ||
|
||
import ( | ||
"io" | ||
"os" | ||
"path" | ||
) | ||
|
||
type Filesystem interface { | ||
GetWriter(filePath string) (io.WriteCloser, error) | ||
GetReader(filePath string) (io.ReadCloser, error) | ||
} | ||
|
||
type LocalFilesystem struct { | ||
root string | ||
} | ||
|
||
func NewLocalFilesystem(root string) *LocalFilesystem { | ||
return &LocalFilesystem{root: root} | ||
} | ||
|
||
func (fs *LocalFilesystem) GetWriter(filePath string) (io.WriteCloser, error) { | ||
return os.Create(path.Join(fs.root, filePath)) | ||
} | ||
func (fs *LocalFilesystem) GetReader(filePath string) (io.ReadCloser, error) { | ||
return os.Open(path.Join(fs.root, filePath)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package controllers | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"crypto/sha256" | ||
"fmt" | ||
"io" | ||
|
||
infrav1 "github.com/weaveworks/tf-controller/api/v1alpha2" | ||
Check failure on line 10 in controllers/tf_controller_blob_cache.go
|
||
"github.com/weaveworks/tf-controller/runner" | ||
Check failure on line 11 in controllers/tf_controller_blob_cache.go
|
||
ctrl "sigs.k8s.io/controller-runtime" | ||
) | ||
|
||
// TODO: This path is hard-coded in the Deployment of the controller as mount | ||
// point. Why not /tmp? Good question, it's a ro mount so we can't write there. | ||
const cacheDir = "/blob-cache" | ||
|
||
func (r *TerraformReconciler) GetWorkspaceBlobCache(ctx context.Context, runnerClient runner.RunnerClient, terraform *infrav1.Terraform, tfInstance, workdir string) error { | ||
log := ctrl.LoggerFrom(ctx).WithValues("step", "get workspace blob cache") | ||
|
||
log.Info("request workspace blob from runner", "workdir", workdir, "tfInstance", tfInstance) | ||
streamClient, err := runnerClient.CreateWorkspaceBlobStream(ctx, &runner.CreateWorkspaceBlobRequest{ | ||
TfInstance: tfInstance, | ||
WorkingDir: workdir, | ||
Namespace: terraform.Namespace, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fs := NewLocalFilesystem(cacheDir) | ||
sha := sha256.New() | ||
checksum := []byte{} | ||
|
||
// TODO: This file pattern needs some love, it's there as a placeholder. | ||
// It would be beneficial if we can add the commit hash to the filename, but | ||
// then it would be problematic to retrieve when the source is not available, | ||
// and that's one of the reasons why we do this in the first place, so we can | ||
// get the cached content even if source is not available. | ||
// | ||
// NOTE: We can use commit hash from Source and if it's not available use from | ||
// lastAppliedRevision, lastAttemptedRevision, or lastPlannedRevision. | ||
file, err := fs.GetWriter(fmt.Sprintf("%s-%s.tar.gz", terraform.GetNamespace(), terraform.GetName())) | ||
if err != nil { | ||
return err | ||
} | ||
defer file.Close() | ||
|
||
for { | ||
chunk, err := streamClient.Recv() | ||
if err != nil { | ||
if err == io.EOF { | ||
if err := streamClient.CloseSend(); err != nil { | ||
log.Error(err, "unabel to close stream") | ||
break | ||
} | ||
} | ||
|
||
return err | ||
} | ||
|
||
if len(chunk.Blob) > 0 { | ||
if _, err := sha.Write(chunk.Blob); err != nil { | ||
return err | ||
} | ||
|
||
if _, err := file.Write(chunk.Blob); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if len(chunk.Sha256Checksum) > 0 { | ||
checksum = chunk.GetSha256Checksum() | ||
} | ||
} | ||
|
||
log.Info("calculating checksum") | ||
sum := sha.Sum(nil) | ||
|
||
if !bytes.Equal(sum, checksum) { | ||
return fmt.Errorf("invalid checksum, got: '%x'; expected: '%x'", sum, checksum) | ||
} | ||
|
||
return nil | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.