Skip to content

Commit

Permalink
Adding support for parsing multiple docs (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
nextrevision authored and cllunsford committed Sep 28, 2016
1 parent 954e013 commit 5da24cd
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 58 deletions.
32 changes: 32 additions & 0 deletions fixtures/deployment-service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
selector:
app: nginx
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
File renamed without changes.
35 changes: 22 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"strings"

"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/yaml"
)

var (
Expand Down Expand Up @@ -74,14 +72,7 @@ func main() {
defer in.Close()
}

// read in doc
data, err := ioutil.ReadAll(in)
if err != nil {
log.Fatal(err)
}

// ensure doc is JSON
data, err = yaml.ToJSON(data)
resources, err := ParseDocs(in)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -148,9 +139,27 @@ func main() {

// inject environment variables into the supplied resource doc
// and print the result to STDOUT
object, err := InjectVars(data, envVars)
if err = printResource(object, toYAML); err != nil {
log.Fatal(err)
for _, resource := range resources {
var result interface{}
switch resource.Kind {
case "Deployment":
result, err = resource.InjectVarsDeployment(envVars)
case "DaemonSet":
result, err = resource.InjectVarsDaemonSet(envVars)
case "ReplicaSet":
result, err = resource.InjectVarsReplicaSet(envVars)
case "ReplicationController":
result, err = resource.InjectVarsRC(envVars)
default:
result, err = resource.UnmarshalGeneric()
}
if err != nil {
log.Fatal(err)
}

if err = printResource(result, toYAML); err != nil {
log.Fatal(err)
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func TestMainWithYAML(t *testing.T) {
"kenv",
"-v",
"fixtures/vars.env",
"fixtures/deployment.yaml",
"fixtures/deployment.yml",
}

main()
Expand Down
93 changes: 60 additions & 33 deletions resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,72 @@ package main

import (
"encoding/json"
"fmt"
"log"
"io"

"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/yaml"
)

func InjectVars(data []byte, envVars []v1.EnvVar) (runtime.Object, error) {
kind, err := getDocKind(data)
if err != nil {
log.Fatal(err)
}
// KubeResource represents a resource kind and raw data to be used
// later for injecting EnvVars
type KubeResource struct {
Kind string
Data []byte
}

// ParseDocs iterates through YAML or JSON docs and discovers
// their type returning a list of KubeResources
func ParseDocs(reader io.Reader) ([]KubeResource, error) {
resources := []KubeResource{}
decoder := yaml.NewYAMLOrJSONDecoder(reader, 4096)

for {
rawExtension := runtime.RawExtension{}
err := decoder.Decode(&rawExtension)
if err == io.EOF {
break
} else if err != nil {
return resources, err
}

switch kind {
case "Deployment":
return injectVarsDeployment(data, envVars)
case "DaemonSet":
return injectVarsDaemonSet(data, envVars)
case "ReplicaSet":
return injectVarsReplicaSet(data, envVars)
case "ReplicationController":
return injectVarsReplicationController(data, envVars)
default:
return &v1beta1.Deployment{}, fmt.Errorf("Kind %s not supported\n", kind)
kind, err := getResourceKind(rawExtension.Raw)
if err != nil {
return resources, err
}

resources = append(resources, KubeResource{
Kind: kind,
Data: rawExtension.Raw,
})
}

return resources, nil
}

// injectVarsDeployment inserts EnvVars into a deployment doc
func injectVarsDeployment(data []byte, envVars []v1.EnvVar) (*v1beta1.Deployment, error) {
// InjectVarsDeployment inserts EnvVars into a Deployment doc
func (k *KubeResource) InjectVarsDeployment(envVars []v1.EnvVar) (*v1beta1.Deployment, error) {
deployment := &v1beta1.Deployment{}
if err := json.Unmarshal(data, deployment); err != nil {

if err := json.Unmarshal(k.Data, &deployment); err != nil {
return deployment, err
}

podSpec := injectPodSpecEnvVars(
deployment.Spec.Template.Spec,
envVars,
)

deployment.Spec.Template.Spec = podSpec
return deployment, nil
}

// injectVarsDaemonSet inserts EnvVars into a daemonSet doc
func injectVarsDaemonSet(data []byte, envVars []v1.EnvVar) (*v1beta1.DaemonSet, error) {
// InjectVarsDaemonSet inserts EnvVars into a daemonSet doc
func (k *KubeResource) InjectVarsDaemonSet(envVars []v1.EnvVar) (*v1beta1.DaemonSet, error) {
daemonSet := &v1beta1.DaemonSet{}

if err := json.Unmarshal(data, daemonSet); err != nil {
if err := json.Unmarshal(k.Data, daemonSet); err != nil {
return daemonSet, err
}

Expand All @@ -63,10 +79,10 @@ func injectVarsDaemonSet(data []byte, envVars []v1.EnvVar) (*v1beta1.DaemonSet,
return daemonSet, nil
}

// injectVarsReplicaSet inserts EnvVars into a replicaSet doc
func injectVarsReplicaSet(data []byte, envVars []v1.EnvVar) (*v1beta1.ReplicaSet, error) {
// InjectVarsReplicaSet inserts EnvVars into a replicaSet doc
func (k *KubeResource) InjectVarsReplicaSet(envVars []v1.EnvVar) (*v1beta1.ReplicaSet, error) {
replicaSet := &v1beta1.ReplicaSet{}
if err := json.Unmarshal(data, replicaSet); err != nil {
if err := json.Unmarshal(k.Data, replicaSet); err != nil {
return replicaSet, err
}

Expand All @@ -79,10 +95,10 @@ func injectVarsReplicaSet(data []byte, envVars []v1.EnvVar) (*v1beta1.ReplicaSet
return replicaSet, nil
}

// injectVarsReplicationController inserts EnvVars into a replicationController doc
func injectVarsReplicationController(data []byte, envVars []v1.EnvVar) (*v1.ReplicationController, error) {
// InjectVarsReplicationController inserts EnvVars into a replicationController doc
func (k *KubeResource) InjectVarsRC(envVars []v1.EnvVar) (*v1.ReplicationController, error) {
replicationController := &v1.ReplicationController{}
if err := json.Unmarshal(data, replicationController); err != nil {
if err := json.Unmarshal(k.Data, replicationController); err != nil {
return replicationController, err
}

Expand All @@ -95,8 +111,19 @@ func injectVarsReplicationController(data []byte, envVars []v1.EnvVar) (*v1.Repl
return replicationController, nil
}

// getDocKind unmarshalls a file and returns the kind of resource doc
func getDocKind(data []byte) (string, error) {
// UnmarshalGeneric does not attempt to unmarshal to a known type,
// instead returns a generic interface object for displaying to the user
func (k *KubeResource) UnmarshalGeneric() (interface{}, error) {
var generic interface{}
if err := json.Unmarshal(k.Data, &generic); err != nil {
return generic, err
}

return generic, nil
}

// getResourceKind unmarshalls a file and returns the kind of resource doc
func getResourceKind(data []byte) (string, error) {
typeMeta := unversioned.TypeMeta{}
if err := json.Unmarshal(data, &typeMeta); err != nil {
return "", err
Expand Down
Loading

0 comments on commit 5da24cd

Please sign in to comment.