github.com/docker/compose-on-kubernetes@v0.5.0/cmd/reconciliation-recorder/main.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"github.com/docker/compose-on-kubernetes/api/client/clientset"
    10  	"github.com/docker/compose-on-kubernetes/api/labels"
    11  	"github.com/docker/compose-on-kubernetes/internal/controller"
    12  	"github.com/docker/compose-on-kubernetes/internal/stackresources"
    13  	"github.com/spf13/cobra"
    14  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    15  	k8sclientset "k8s.io/client-go/kubernetes"
    16  	"k8s.io/client-go/tools/clientcmd"
    17  )
    18  
    19  type options struct {
    20  	kubeconfig string
    21  	namespace  string
    22  	outdir     string
    23  }
    24  
    25  func main() {
    26  	opts := &options{}
    27  	cmd := &cobra.Command{
    28  		Use: "reconciliation-recorder [OPTIONS] [stack name [stack name...]]",
    29  		RunE: func(c *cobra.Command, args []string) error {
    30  			return run(args, opts)
    31  		},
    32  	}
    33  
    34  	cmd.Flags().StringVar(&opts.kubeconfig, "kubeconfig", "", "kubeconfig path")
    35  	cmd.Flags().StringVarP(&opts.namespace, "namespace", "n", "default", "namespace of the stack to capture")
    36  	cmd.Flags().StringVarP(&opts.outdir, "out", "o", "./out", "output directory where to put assets")
    37  	if err := cmd.Execute(); err != nil {
    38  		panic(err)
    39  	}
    40  }
    41  
    42  func run(stacksToProceed []string, opts *options) error {
    43  	if err := os.MkdirAll(opts.outdir, 0755); err != nil {
    44  		return err
    45  	}
    46  	loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
    47  	loadingRules.ExplicitPath = opts.kubeconfig
    48  	cmdConfig, err := loadingRules.Load()
    49  	if err != nil {
    50  		return err
    51  	}
    52  	clientCfg := clientcmd.NewDefaultClientConfig(*cmdConfig, &clientcmd.ConfigOverrides{})
    53  	restCfg, err := clientCfg.ClientConfig()
    54  	if err != nil {
    55  		return err
    56  	}
    57  	stacks, err := clientset.NewForConfig(restCfg)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	k8sclient, err := k8sclientset.NewForConfig(restCfg)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	if len(stacksToProceed) == 0 {
    66  		allStacks, err := stacks.ComposeLatest().Stacks(opts.namespace).List(metav1.ListOptions{})
    67  		if err != nil {
    68  			return err
    69  		}
    70  		for _, s := range allStacks.Items {
    71  			stacksToProceed = append(stacksToProceed, s.Name)
    72  		}
    73  	}
    74  	for _, name := range stacksToProceed {
    75  		if err = processStack(stacks, k8sclient, name, opts.namespace, opts.outdir); err != nil {
    76  			return err
    77  		}
    78  	}
    79  	return nil
    80  }
    81  
    82  func processStack(stacks clientset.Interface, k8sclient k8sclientset.Interface, name, namespace, outdir string) error {
    83  	stack, err := stacks.ComposeLatest().Stacks(namespace).Get(name, metav1.GetOptions{})
    84  	if err != nil {
    85  		return err
    86  	}
    87  	services, err := k8sclient.CoreV1().Services(namespace).List(metav1.ListOptions{LabelSelector: labels.SelectorForStack(name)})
    88  	if err != nil {
    89  		return err
    90  	}
    91  	deployments, err := k8sclient.AppsV1().Deployments(namespace).List(metav1.ListOptions{LabelSelector: labels.SelectorForStack(name)})
    92  	if err != nil {
    93  		return err
    94  	}
    95  	daemonsets, err := k8sclient.AppsV1().DaemonSets(namespace).List(metav1.ListOptions{LabelSelector: labels.SelectorForStack(name)})
    96  	if err != nil {
    97  		return err
    98  	}
    99  	statefulsets, err := k8sclient.AppsV1().StatefulSets(namespace).List(metav1.ListOptions{LabelSelector: labels.SelectorForStack(name)})
   100  	if err != nil {
   101  		return err
   102  	}
   103  	var allResources []interface{}
   104  	for _, r := range services.Items {
   105  		local := r
   106  		allResources = append(allResources, &local)
   107  	}
   108  	for _, r := range deployments.Items {
   109  		local := r
   110  		allResources = append(allResources, &local)
   111  	}
   112  	for _, r := range daemonsets.Items {
   113  		local := r
   114  		allResources = append(allResources, &local)
   115  	}
   116  	for _, r := range statefulsets.Items {
   117  		local := r
   118  		allResources = append(allResources, &local)
   119  	}
   120  	childrenState, err := stackresources.NewStackState(allResources...)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	tc := &controller.TestCase{
   125  		Stack:    stack,
   126  		Children: childrenState,
   127  	}
   128  	payload, err := json.Marshal(tc)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	path := filepath.Join(outdir, name+".json")
   133  	return ioutil.WriteFile(path, payload, 0644)
   134  }