func main()

in grove/grovetccfg/grovetccfg.go [189:350]


func main() {
	toURL := flag.String("tourl", "", "The Traffic Ops URL")
	toUser := flag.String("touser", "", "The Traffic Ops username")
	toPass := flag.String("topass", "", "The Traffic Ops password")
	pretty := flag.Bool("pretty", false, "Whether to pretty-print output")
	ignoreUpdateFlag := flag.Bool("ignore-update-flag", false, "Whether to fetch and apply the config, without checking or updating the Traffic Ops Update Pending flag")
	host := flag.String("host", "", "The hostname of the server whose config to generate")
	toInsecure := flag.Bool("insecure", false, "Whether to allow invalid certificates with Traffic Ops")
	certDir := flag.String("certdir", DefaultCertificateDir, "Directory to save certificates to")
	noServiceReload := flag.Bool("no-service-reload", false, "Whether to avoid trying to reload the Grove service")
	flag.Parse()

	if host == nil || *host == "" {
		// if the host was not specified on the command line, get it from the kernel
		h, err := os.Hostname()
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + err.Error() + " and 'host' is required, use '-host'")
			os.Exit(ExitError)
		}
		sl := strings.Split(h, ".")
		*host = sl[0]
	}

	useCache := false
	toc, _, err := to.LoginWithAgent(*toURL, *toUser, *toPass, *toInsecure, UserAgent, useCache, TrafficOpsTimeout)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error connecting to Traffic Ops: " + err.Error())
		os.Exit(ExitError)
	}

	revalPendingStatus := false
	if !*ignoreUpdateFlag {
		needsUpdate := false
		needsUpdate, revalPendingStatus, err = hasUpdatePending(toc, *host)
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error checking Traffic Ops update pending: " + err.Error())
			os.Exit(ExitError)
		}
		if !needsUpdate {
			os.Exit(ExitSuccess) // if no error and no update necessary, return success and print nothing
		}
	}

	// TODO remove this once converted to 1.3 API
	// using the 1.2 API
	var hostServer tc.ServerV30
	var hostProfile tc.Profile
	var ok bool
	var profiles map[string]tc.Profile
	var servers map[string]tc.ServerV30

	serversArr, _, err := toc.GetServersWithHdr(nil, nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Servers: " + err.Error())
		os.Exit(ExitError)
	}
	servers = makeServersHostnameMap(serversArr.Response)

	hostServer, ok = servers[*host]
	if !ok {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error: host '" + *host + "' not in Servers\n")
		os.Exit(ExitError)
	}

	profilesArr, _, err := toc.GetProfilesWithHdr(nil)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting Traffic Ops Profiles: " + err.Error())
		os.Exit(ExitError)
	}
	profiles = makeProfileNameMap(profilesArr)

	hostProfile, ok = profiles[*hostServer.Profile]
	if !ok {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error: profile '" + *hostServer.Profile + "' not in Profiles\n")
		os.Exit(ExitError)
	}
	// end of API 1.2 stuff

	if hostProfile.Type == tc.GroveProfileType {
		updateRequired, cfg, err := createGroveCfg(toc, hostServer)
		if err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting config rules for '" + GroveConfigPath + "' :" + err.Error())
			os.Exit(ExitError)
		}
		if updateRequired {
			cfgBytes := []byte{}
			if *pretty {
				cfgBytes, err = json.MarshalIndent(cfg, "", "  ")
			} else {
				cfgBytes, err = json.Marshal(cfg)
			}
			if err != nil {
				fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error creating JSON Remap Rules: " + err.Error())
				os.Exit(ExitError)
			}
			if err := WriteAndBackup(GroveConfigPath, ConfigHistory, cfgBytes); err != nil {
				fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error writing new config file: " + err.Error())
				os.Exit(ExitError)
			}
		}
	} else {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Warning: the profile '" + *hostServer.Profile + "' is not a '" + tc.GroveProfileType + "', will not build a config from it.")
	}

	rules := remap.RemapRules{}
	// if *api == "1.3" {
	// 	rules, err = createRulesNewAPI(toc, *host, *certDir)
	// } else {
	rules, err = createRulesOldAPI(toc, *host, *certDir, servers) // TODO remove once 1.3 / traffic_ops_golang is deployed to production.
	// }
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error creating rules: " + err.Error())
		os.Exit(ExitError)
	}

	jsonRules, err := remap.RemapRulesToJSON(rules)
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error creating JSON Remap Rules: " + err.Error())
		os.Exit(ExitError)
	}

	bts := []byte{}
	if *pretty {
		bts, err = json.MarshalIndent(jsonRules, "", "  ")
	} else {
		bts, err = json.Marshal(jsonRules)
	}

	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error marshalling rules JSON: " + err.Error())
		os.Exit(ExitError)
	}

	// TODO add app/option to print config to stdout

	remapPath, err := GetRemapPath()
	if err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error getting remap config path: " + err.Error())
		os.Exit(ExitError)
	}

	if err := WriteAndBackup(remapPath, RemapHistory, bts); err != nil {
		fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error writing new config file: " + err.Error())
		os.Exit(ExitError)
	}

	if !*noServiceReload {
		if err := exec.Command("service", "grove", "reload").Run(); err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error restarting grove service (but successfully updated config file): " + err.Error())
			os.Exit(ExitErrorReloadingService)
		}
	}

	if !*ignoreUpdateFlag {
		if err := clearUpdatePending(toc, *host, revalPendingStatus); err != nil {
			fmt.Println(time.Now().Format(time.RFC3339Nano) + " Error clearing update pending flag in Traffic Ops (but successfully updated config): " + err.Error())
			os.Exit(ExitErrorClearingUpdateFlag)
		}
	}

	os.Exit(ExitSuccess)
}