Skip to content

Instantly share code, notes, and snippets.

@griggheo
Created August 28, 2014 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save griggheo/bf2143e9bc1404345511 to your computer and use it in GitHub Desktop.
Save griggheo/bf2143e9bc1404345511 to your computer and use it in GitHub Desktop.
Inspect differences between Chef environments on Chef server vs local filesystem
package main
import (
"fmt"
"log"
"bytes"
"strings"
"flag"
"sort"
"os/exec"
"io/ioutil"
)
func getChefEnvironment(environment *string, verbose bool) map[string]string {
fmt.Println("\nGetting Chef cookbook versions for environment:", *environment)
cmd := exec.Command("knife", "environment", "show", *environment)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
//fmt.Printf("%s\n", out.String())
lines := strings.Split(out.String(), "\n")
m := make(map[string]string)
keys := make([]string, 0, len(lines))
var cookbook, version string;
for _, line := range lines {
if ! strings.Contains(line, "=") {
continue
}
//fmt.Println(line)
values := strings.Split(line, "=")
/*
for _, value := range values {
fmt.Printf("value: %s\n", value)
}
*/
cookbook = strings.Trim(values[0], ": ")
version = strings.Trim(values[1], " ")
m[cookbook] = version
keys = append(keys, cookbook)
}
if verbose {
sort.Strings(keys)
for _, key := range keys {
fmt.Printf("cookbook \"%s\" has version \"%s\"\n", key, m[key])
}
}
return m
}
func getLocalEnvironment(environment *string, verbose bool) map[string]string {
fmt.Println("\nGetting local cookbook versions for environment:", *environment)
filename := fmt.Sprintf("/Users/grig.gheorghiu/chef-repo/environments/%s.rb", *environment)
content, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatalln("Error reading file", filename)
}
// content returned as []byte not string
lines := strings.Split(string(content), "\n")
m := make(map[string]string)
keys := make([]string, 0, len(lines))
var cookbook, version string;
for _, line := range lines {
if ! strings.Contains(line, "=") {
continue
}
line = strings.Replace(line, "\"", "", -1)
line = strings.Replace(line, ",", "", -1)
line = strings.Replace(line, "cookbook", "", -1)
//fmt.Println(line)
values := strings.Split(line, "=")
/*
for _, value := range values {
fmt.Printf("value: %s\n", value)
}
*/
cookbook = strings.Trim(values[0], ": ")
version = strings.Trim(values[1], " ")
m[cookbook] = version
keys = append(keys, cookbook)
}
if verbose {
sort.Strings(keys)
for _, key := range keys {
fmt.Printf("cookbook \"%s\" has version \"%s\"\n", key, m[key])
}
}
return m
}
func main() {
environment := flag.String("env", "prod", "the environment we are inspecting")
flag.Parse()
from_chef := getChefEnvironment(environment, false)
for cookbook, version := range from_chef {
fmt.Printf("Chef cookbook \"%s\" has version \"%s\"\n", cookbook, version)
}
from_local := getLocalEnvironment(environment, false)
for cookbook, version := range from_local {
fmt.Printf("Local cookbook \"%s\" has version \"%s\"\n", cookbook, version)
}
found := false
for key := range from_local {
if from_chef[key] != from_local[key] {
fmt.Printf("\nFound a difference for %s! Local: %s Chef: %s\n", key, from_local[key], from_chef[key])
found = true
}
}
if ! found {
fmt.Printf("\nFound no differences between Chef and local!\n")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment