Skip to content
This repository has been archived by the owner on Feb 10, 2021. It is now read-only.

Commit

Permalink
Consume JSON output from microconfig (#2)
Browse files Browse the repository at this point in the history
* Consume JSON output from microconfig

* Update README.md

* Update microconfig release in CI
  • Loading branch information
Stepan Rakitin authored Jun 20, 2020
1 parent bab9fba commit e4d2439
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 151 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ jobs:
sudo unzip microconfig.zip -d /usr/local/bin
sudo chmod +x /usr/local/bin/microconfig
env:
MICROCONFIG_RELEASE: v4.1.2
MICROCONFIG_RELEASE: v4.1.4
- name: Download dependencies
run: go mod download
- name: Test
run: |
MICROCONFIG_SOURCE_DIR=$(pwd)/fixtures \
MICROCONFIG_DESTINATION_DIR=$(pwd)/build \
make testacc
env:
MICROCONFIG_PATH: /usr/local/bin/microconfig
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ This provider enables [microconfig](https://github.com/microconfig/microconfig)
```terraform
provider "microconfig" {
source_dir = "fixtures"
destination_dir = "build"
entrypoint = "/usr/bin/microconfig"
}
Expand All @@ -21,6 +20,6 @@ resource "microconfig_service" "payment-backend" {
}
output "data" {
value = microconfig_service.payment-backend.data["application.yaml"]
value = yamldecode(microconfig_service.payment-backend.data["application.yaml"])
}
```
3 changes: 1 addition & 2 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
provider "microconfig" {
source_dir = "fixtures"
destination_dir = "build"
entrypoint = "/usr/bin/microconfig"
}

Expand All @@ -10,5 +9,5 @@ resource "microconfig_service" "payment-backend" {
}

output "data" {
value = microconfig_service.payment-backend.data
value = yamldecode(microconfig_service.payment-backend.data["application.yaml"])
}
11 changes: 1 addition & 10 deletions microconfig/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ func Provider() *schema.Provider {
Required: true,
DefaultFunc: schema.EnvDefaultFunc("MICROCONFIG_SOURCE_DIR", nil),
},
"destination_dir": {
Type: schema.TypeString,
Description: "Full or relative build destination dir",
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("MICROCONFIG_DESTINATION_DIR", "build"),
},
},
ResourcesMap: map[string]*schema.Resource{
"microconfig_service": resourceMicroconfigService(),
Expand All @@ -38,21 +32,19 @@ func Provider() *schema.Provider {
type commandFactory func(env string, serviceName string) *exec.Cmd

type providerMeta struct {
DestinationDir string
CommandFactory commandFactory
}

func providerConfigure(d *schema.ResourceData) (interface{}, error) {
entrypoint := d.Get("entrypoint").(string)
sourceDir := d.Get("source_dir").(string)
destinationDir := d.Get("destination_dir").(string)

cmdFactory := func(env string, serviceName string) *exec.Cmd {
args := []string{entrypoint}
args = append(args, "-r", sourceDir)
args = append(args, "-d", destinationDir)
args = append(args, "-e", env)
args = append(args, "-s", serviceName)
args = append(args, "-output", "json")

return &exec.Cmd{
Path: entrypoint,
Expand All @@ -61,7 +53,6 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
}

return providerMeta{
DestinationDir: destinationDir,
CommandFactory: cmdFactory,
}, nil
}
154 changes: 20 additions & 134 deletions microconfig/resource_microconfig_service.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package microconfig

import (
"archive/tar"
"bytes"
"crypto/sha1"
"encoding/hex"
"fmt"
"io"
"os"
"path/filepath"
"encoding/json"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

type serviceResult struct {
Service string `json:"service"`
Files []struct {
Filename string `json:"fileName"`
Content string `json:"content"`
} `json:"files"`
}

func resourceMicroconfigService() *schema.Resource {
return &schema.Resource{
Create: resourceMicroconfigServiceCreate,
Create: resourceMicroconfigServiceRead,
Read: resourceMicroconfigServiceRead,
Delete: resourceMicroconfigServiceDelete,
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -43,60 +46,32 @@ func resourceMicroconfigService() *schema.Resource {
}
}

func resourceMicroconfigServiceCreate(d *schema.ResourceData, m interface{}) error {
func resourceMicroconfigServiceRead(d *schema.ResourceData, m interface{}) error {
meta := m.(providerMeta)
env := d.Get("environment").(string)
serviceName := d.Get("name").(string)

if err := resourceMicroconfigServiceDelete(d, meta); err != nil {
return err
}

cmd := meta.CommandFactory(env, serviceName)

err := cmd.Run()
out, err := cmd.Output()
if err != nil {
return err
}

serviceDir := filepath.Join(meta.DestinationDir, serviceName)
checksum := sha1.Sum(out)
hash := hex.EncodeToString(checksum[:])
d.SetId(hash)

hash, err := generateDirHash(serviceDir)
if err != nil {
var results []serviceResult
if err := json.Unmarshal(out, &results); err != nil {
return err
}
d.SetId(hash)

result := results[0]
data := make(map[string]string)

if err := filepath.Walk(serviceDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}

f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()

buf := new(bytes.Buffer)

if _, err := io.Copy(buf, f); err != nil {
return err
}

relPath, _ := filepath.Rel(serviceDir, path)

data[relPath] = buf.String()

return nil
}); err != nil {
return err
for _, file := range result.Files {
data[file.Filename] = file.Content
}

d.Set("data", data)
Expand All @@ -106,94 +81,5 @@ func resourceMicroconfigServiceCreate(d *schema.ResourceData, m interface{}) err

func resourceMicroconfigServiceDelete(d *schema.ResourceData, m interface{}) error {
d.SetId("")

meta := m.(providerMeta)
serviceName := d.Get("name").(string)

serviceDir := filepath.Join(meta.DestinationDir, serviceName)
if _, err := os.Stat(serviceDir); os.IsNotExist(err) {
return nil
}

if err := os.RemoveAll(serviceDir); err != nil {
return fmt.Errorf("could not delete directory %q: %s", serviceDir, err)
}

return nil
}

func resourceMicroconfigServiceRead(d *schema.ResourceData, m interface{}) error {
meta := m.(providerMeta)
serviceName := d.Get("name").(string)
serviceDir := filepath.Join(meta.DestinationDir, serviceName)

if _, err := os.Stat(serviceDir); os.IsNotExist(err) {
d.SetId("")
return nil
}

hash, err := generateDirHash(serviceDir)
if err != nil {
return err
}
if hash != d.Id() {
d.SetId("")
return nil
}

return nil
}

func generateDirHash(dir string) (string, error) {
tarData, err := tarDir(dir)
if err != nil {
return "", fmt.Errorf("could not generate output checksum: %s", err)
}

checksum := sha1.Sum(tarData)
return hex.EncodeToString(checksum[:]), nil
}

func tarDir(dir string) ([]byte, error) {
buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)

writeToTar := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

h, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return err
}
relPath, _ := filepath.Rel(dir, path)
h.Name = relPath

if err := tw.WriteHeader(h); err != nil {
return err
}

if info.IsDir() {
return nil
}

f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()

_, err = io.Copy(tw, f)
return err
}

if err := filepath.Walk(dir, writeToTar); err != nil {
return []byte{}, err
}
if err := tw.Flush(); err != nil {
return []byte{}, err
}

return buf.Bytes(), nil
}
2 changes: 1 addition & 1 deletion microconfig/resource_microconfig_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ resource "microconfig_service" "payment-backend" {
Steps: []resource.TestStep{
{
Config: testResourceMicroconfigServiceCreateConfig,
Check: resource.TestCheckResourceAttr("microconfig_service.payment-backend", "data.%", "3"),
Check: resource.TestCheckResourceAttr("microconfig_service.payment-backend", "data.%", "2"),
},
},
})
Expand Down

0 comments on commit e4d2439

Please sign in to comment.