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)
}