github.com/flanksource/konfigadm@v0.12.0/cmd/apply.go (about)

     1  package cmd
     2  
     3  import (
     4  	"io/ioutil"
     5  	"net/http"
     6  	"os"
     7  	"path/filepath"
     8  	"strconv"
     9  
    10  	"github.com/flanksource/konfigadm/pkg/ansible"
    11  	"github.com/flanksource/konfigadm/pkg/types"
    12  	"github.com/flanksource/konfigadm/pkg/utils"
    13  	log "github.com/sirupsen/logrus"
    14  	"github.com/spf13/cobra"
    15  )
    16  
    17  var (
    18  	Apply = cobra.Command{
    19  		Use:   "apply",
    20  		Short: "Apply the configuration to the local machine or remote machines over SSH",
    21  		Args:  cobra.MinimumNArgs(0),
    22  		Run: func(cmd *cobra.Command, args []string) {
    23  			cfg := GetConfig(cmd, args)
    24  
    25  			var remoteHosts []string
    26  			if inventory, _ := cmd.Flags().GetString("inventory"); inventory != "" {
    27  				remoteHosts = ansible.ParseInventory(inventory)
    28  				port, _ := cmd.Flags().GetInt("port")
    29  				cmd, err := cfg.ToBash()
    30  				if err != nil {
    31  					panic(err)
    32  				}
    33  				for _, host := range remoteHosts {
    34  					ansible.ExecuteRemoteCommand(cmd, host, port)
    35  				}
    36  			} else {
    37  				runLocal(cfg)
    38  			}
    39  
    40  		},
    41  	}
    42  )
    43  
    44  func runLocal(cfg *types.Config) {
    45  	files, commands, err := cfg.ApplyPhases()
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  
    50  	for path, file := range files {
    51  		log.Infof("Writing %s\n", utils.LightGreenf(path))
    52  		perms, _ := strconv.Atoi(file.Permissions)
    53  		if perms == 0 {
    54  			perms = 0644
    55  		}
    56  		content := []byte(file.Content)
    57  		if file.Content == "" && file.ContentFromURL != "" {
    58  			log.Infof("Downloading %s to path %s", file.ContentFromURL, path)
    59  			resp, err := http.Get(file.ContentFromURL)
    60  			if err != nil {
    61  				log.Errorf("Failed to download from url %s: %v", file.ContentFromURL, err)
    62  				continue
    63  			}
    64  			defer resp.Body.Close()
    65  			c, err := ioutil.ReadAll(resp.Body)
    66  			if err != nil {
    67  				log.Errorf("Failed to read response body from url %s: %v", file.ContentFromURL, err)
    68  				continue
    69  			}
    70  			content = c
    71  		}
    72  
    73  		dirMode := perms + 111
    74  		dirName := filepath.Dir(path)
    75  		if _, serr := os.Stat(dirName); serr != nil {
    76  			merr := os.MkdirAll(dirName, os.FileMode(dirMode))
    77  			if merr != nil {
    78  				log.Errorf("Failed to mkdir %s: %v", utils.Redf(dirName), err)
    79  			}
    80  		}
    81  
    82  		if err := ioutil.WriteFile(path, []byte(content), os.FileMode(perms)); err != nil {
    83  			log.Errorf("Failed to write file %s: %v", utils.Redf(path), err)
    84  		}
    85  	}
    86  
    87  	for _, cmd := range commands {
    88  		log.Infof("Executing %s\n", utils.LightGreenf(cmd.Cmd))
    89  		if err := utils.Exec(cmd.Cmd); err != nil {
    90  			log.Fatalf("Failed to run: %s, %s", cmd.Cmd, err)
    91  		}
    92  	}
    93  }
    94  
    95  func init() {
    96  	Apply.Flags().String("inventory", "", "An ansible inventory to apply the configuration to")
    97  	Apply.Flags().Int("port", 22, "The SSH port to use for applying the configuration remotely. Defaults to port 22")
    98  }