This is an automated email from the ASF dual-hosted git repository.
rob pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new 82314b1 Add the Traffic Ops ORT requester. (#5468)
82314b1 is described below
commit 82314b1f3fa91f786adf3ab15379ecdf5cb7b259
Author: John J. Rushford <[email protected]>
AuthorDate: Wed Feb 3 13:44:06 2021 -0700
Add the Traffic Ops ORT requester. (#5468)
---
traffic_ops_ort/to_requester/README.md | 68 +++++++
traffic_ops_ort/to_requester/config/config.go | 177 ++++++++++++++++++
traffic_ops_ort/to_requester/getdata/getdata.go | 229 ++++++++++++++++++++++++
traffic_ops_ort/to_requester/to_requester.go | 134 ++++++++++++++
4 files changed, 608 insertions(+)
diff --git a/traffic_ops_ort/to_requester/README.md
b/traffic_ops_ort/to_requester/README.md
new file mode 100644
index 0000000..4e46e9a
--- /dev/null
+++ b/traffic_ops_ort/to_requester/README.md
@@ -0,0 +1,68 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+# Traffic Ops Requester
+
+## Synopsis
+ to_requester [-hI] [-D value] [-d value] [-e value] [-H value] [-i
value] \
+ [-l value] [-P value] [-t value] [-u value] [-U value]
+
+## Description
+ The to_requester is used get update status, package information, linux
+ chkconfig status, system info and status from Traffic Ops, see the
+ --get-data option. If no --get-data option is specified, the servers
+ system-info is fetched and returned.
+
+## Options
+ -D, --get-data=value
+ non-config-file Traffic Ops Data to get. Valid values are
+ update-status, packages, chkconfig, system-info, and
+ statuses [system-info]
+ -d, --log-location-debug=value
+ Where to log debugs. May be a file path, stdout or stderr.
+ Default is no debug logging.
+ -e, --log-location-error=value
+ Where to log errors. May be a file path, stdout, or stderr.
+ Default is stderr.
+ -i, --log-location-info=value
+ Where to log infos. May be a file path, stdout or stderr.
+ Default is stderr.
+ -H, --cache-host-name=value
+ Host name of the cache to generate config for. Must be the
+ server host name in Traffic Ops, not a URL, and not the FQDN.
+ Defaults to the OS configured hostname.
+ -h, --help Print usage information and exit
+ -I, --traffic-ops-insecure
+ [true | false] ignore certificate errors from
Traffic Ops
+ -l, --login-dispersion=value
+ [seconds] wait a random number of seconds between 0 and
+ [seconds] before login to traffic ops, default 0
+ -P, --traffic-ops-password=value
+ Traffic Ops password. Required. May also be set with the
+ environment variable TO_PASS
+ -t, --traffic-ops-timeout-milliseconds=value
+ Timeout in milli-seconds for Traffic Ops requests, default
+ is 30000 [30000]
+ -u, --traffic-ops-url=value
+ Traffic Ops URL. Must be the full URL, including the scheme.
+ Required. May also be set with the environment variable
+ TO_URL
+ -U, --traffic-ops-user=value
+ Traffic Ops username. Required. May also be set with the
+ environment variable TO_USER
diff --git a/traffic_ops_ort/to_requester/config/config.go
b/traffic_ops_ort/to_requester/config/config.go
new file mode 100644
index 0000000..79c2092
--- /dev/null
+++ b/traffic_ops_ort/to_requester/config/config.go
@@ -0,0 +1,177 @@
+package config
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+ "errors"
+ "fmt"
+ "net/url"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-log"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/atstccfg/toreq"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/atstccfg/toreqnew"
+ "github.com/pborman/getopt/v2"
+)
+
+const AppName = "to_requester"
+const Version = "0.1"
+const UserAgent = AppName + "/" + Version
+
+type Cfg struct {
+ CommandArgs []string
+ LogLocationDebug string
+ LogLocationError string
+ LogLocationInfo string
+ LoginDispersion time.Duration
+ CacheHostName string
+ GetData string
+ TOInsecure bool
+ TOTimeoutMS time.Duration
+ TOUser string
+ TOPass string
+ TOURL *url.URL
+}
+
+type TCCfg struct {
+ Cfg
+ TOClient *toreq.TOClient
+ TOClientNew *toreqnew.TOClient
+}
+
+func (cfg Cfg) DebugLog() log.LogLocation { return
log.LogLocation(cfg.LogLocationDebug) }
+func (cfg Cfg) ErrorLog() log.LogLocation { return
log.LogLocation(cfg.LogLocationError) }
+func (cfg Cfg) InfoLog() log.LogLocation { return
log.LogLocation(cfg.LogLocationInfo) }
+func (cfg Cfg) WarningLog() log.LogLocation { return
log.LogLocation(log.LogLocationNull) } // warn logging is not used.
+func (cfg Cfg) EventLog() log.LogLocation { return
log.LogLocation(log.LogLocationNull) } // event logging is not used.
+
+// Usage() writes command line options and usage to 'stderr'
+func Usage() {
+ getopt.PrintUsage(os.Stderr)
+ os.Exit(0)
+}
+
+// InitConfig() intializes the configuration variables and loggers.
+func InitConfig() (Cfg, error) {
+
+ logLocationDebugPtr := getopt.StringLong("log-location-debug", 'd', "",
"Where to log debugs. May be a file path, stdout, stderr")
+ logLocationErrorPtr := getopt.StringLong("log-location-error", 'e',
"stderr", "Where to log errors. May be a file path, stdout, stderr")
+ logLocationInfoPtr := getopt.StringLong("log-location-info", 'i',
"stderr", "Where to log infos. May be a file path, stdout, stderr")
+ dispersionPtr := getopt.IntLong("login-dispersion", 'l', 0, "[seconds]
wait a random number of seconds between 0 and [seconds] before login to traffic
ops, default 0")
+ cacheHostNamePtr := getopt.StringLong("cache-host-name", 'H', "", "Host
name of the cache to generate config for. Must be the server host name in
Traffic Ops, not a URL, and not the FQDN")
+ getDataPtr := getopt.StringLong("get-data", 'D', "system-info",
"non-config-file Traffic Ops Data to get. Valid values are all, update-status,
packages, chkconfig, system-info, and statuses")
+ toInsecurePtr := getopt.BoolLong("traffic-ops-insecure", 'I', "[true |
false] ignore certificate errors from Traffic Ops")
+ toTimeoutMSPtr := getopt.IntLong("traffic-ops-timeout-milliseconds",
't', 30000, "Timeout in milli-seconds for Traffic Ops requests, default is
30000")
+ toURLPtr := getopt.StringLong("traffic-ops-url", 'u', "", "Traffic Ops
URL. Must be the full URL, including the scheme. Required. May also be set with
the environment variable TO_URL")
+ toUserPtr := getopt.StringLong("traffic-ops-user", 'U', "", "Traffic
Ops username. Required. May also be set with the environment variable TO_USER")
+ toPassPtr := getopt.StringLong("traffic-ops-password", 'P', "",
"Traffic Ops password. Required. May also be set with the environment variable
TO_PASS ")
+ helpPtr := getopt.BoolLong("help", 'h', "Print usage information and
exit")
+
+ getopt.Parse()
+
+ if *helpPtr == true {
+ Usage()
+ }
+
+ dispersion := time.Second * time.Duration(*dispersionPtr)
+ toTimeoutMS := time.Millisecond * time.Duration(*toTimeoutMSPtr)
+ toURL := *toURLPtr
+ toUser := *toUserPtr
+ toPass := *toPassPtr
+
+ urlSourceStr := "argument" // for error messages
+ if toURL == "" {
+ urlSourceStr = "environment variable"
+ toURL = os.Getenv("TO_URL")
+ }
+ if toUser == "" {
+ toUser = os.Getenv("TO_USER")
+ }
+ if *toPassPtr == "" {
+ toPass = os.Getenv("TO_PASS")
+ }
+
+ toURLParsed, err := url.Parse(toURL)
+ if err != nil {
+ return Cfg{}, errors.New("parsing Traffic Ops URL from " +
urlSourceStr + " '" + toURL + "': " + err.Error())
+ } else if err := ValidateURL(toURLParsed); err != nil {
+ return Cfg{}, errors.New("invalid Traffic Ops URL from " +
urlSourceStr + " '" + toURL + "': " + err.Error())
+ }
+
+ var cacheHostName string
+ if len(*cacheHostNamePtr) > 0 {
+ cacheHostName = *cacheHostNamePtr
+ } else {
+ cacheHostName, err = os.Hostname()
+ if err != nil {
+ return Cfg{}, errors.New("could not get the OS
hostname, please supply a hostname: " + err.Error())
+ }
+ }
+
+ cfg := Cfg{
+ CommandArgs: getopt.Args(),
+ LogLocationDebug: *logLocationDebugPtr,
+ LogLocationError: *logLocationErrorPtr,
+ LogLocationInfo: *logLocationInfoPtr,
+ LoginDispersion: dispersion,
+ CacheHostName: cacheHostName,
+ GetData: *getDataPtr,
+ TOInsecure: *toInsecurePtr,
+ TOTimeoutMS: toTimeoutMS,
+ TOUser: toUser,
+ TOPass: toPass,
+ TOURL: toURLParsed,
+ }
+
+ if err := log.InitCfg(cfg); err != nil {
+ return Cfg{}, errors.New("initializing loggers: " + err.Error())
+ }
+
+ return cfg, nil
+}
+
+func ValidateURL(u *url.URL) error {
+ if u == nil {
+ return errors.New("nil url")
+ }
+ if u.Scheme != "http" && u.Scheme != "https" {
+ return errors.New("scheme expected 'http' or 'https', actual '"
+ u.Scheme + "'")
+ }
+ if strings.TrimSpace(u.Host) == "" {
+ return errors.New("no host")
+ }
+ return nil
+}
+
+func (cfg Cfg) PrintConfig() {
+ fmt.Printf("CommandArgs: %s\n", cfg.CommandArgs)
+ fmt.Printf("LogLocationDebug: %s\n", cfg.LogLocationDebug)
+ fmt.Printf("LogLocationError: %s\n", cfg.LogLocationError)
+ fmt.Printf("LogLocationInfo: %s\n", cfg.LogLocationInfo)
+ fmt.Printf("LoginDispersion : %s\n", cfg.LoginDispersion)
+ fmt.Printf("CacheHostName: %s\n", cfg.CacheHostName)
+ fmt.Printf("TOInsecure: %s\n", cfg.TOInsecure)
+ fmt.Printf("TOTimeoutMS: %s\n", cfg.TOTimeoutMS)
+ fmt.Printf("TOUser: %s\n", cfg.TOUser)
+ fmt.Printf("TOPass: xxxxxx\n")
+ fmt.Printf("TOURL: %s\n", cfg.TOURL)
+}
diff --git a/traffic_ops_ort/to_requester/getdata/getdata.go
b/traffic_ops_ort/to_requester/getdata/getdata.go
new file mode 100644
index 0000000..b2a0ac9
--- /dev/null
+++ b/traffic_ops_ort/to_requester/getdata/getdata.go
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// package getdata gets and posts non-config data from Traffic Ops which is
related to config generation and needed by ORT.
+// For example, the --get-data, --set-queue-status, and --set-reval-status
arguments.
+package getdata
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "os"
+
+ "github.com/apache/trafficcontrol/lib/go-atscfg"
+ "github.com/apache/trafficcontrol/lib/go-log"
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/atstccfg/toreq"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/atstccfg/toreqnew"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/to_requester/config"
+)
+
+func GetDataFuncs() map[string]func(config.TCCfg, io.Writer) error {
+ return map[string]func(config.TCCfg, io.Writer) error{
+ `update-status`: WriteServerUpdateStatus,
+ `packages`: WritePackages,
+ `chkconfig`: WriteChkconfig,
+ `system-info`: WriteSystemInfo,
+ `statuses`: WriteStatuses,
+ }
+}
+
+func WriteData(cfg config.TCCfg) error {
+ log.Infoln("Getting data '" + cfg.GetData + "'")
+ dataF, ok := GetDataFuncs()[cfg.GetData]
+ if !ok {
+ return errors.New("unknown data request '" + cfg.GetData + "'")
+ }
+ return dataF(cfg, os.Stdout)
+}
+
+const SystemInfoParamConfigFile = `global`
+
+// WriteSystemInfo writes the "system info" to output.
+//
+// This is the same info at /api/1.x/system/info, which is actually just all
Parameters with the config_file 'global'.
+// Note this is different than the more common "global parameters", which
usually refers to all Parameters on the Profile named 'GLOBAL'.
+//
+// This is identical to the /api/1.x/system/info endpoint, except it does not
include a '{response: {parameters:' wrapper.
+//
+func WriteSystemInfo(cfg config.TCCfg, output io.Writer) error {
+ paramArr, _, err :=
cfg.TOClient.GetConfigFileParameters(SystemInfoParamConfigFile)
+ if err != nil {
+ return errors.New("getting system info parameters: " +
err.Error())
+ }
+ params := map[string]string{}
+ for _, param := range paramArr {
+ params[param.Name] = param.Value
+ }
+ if err := json.NewEncoder(output).Encode(params); err != nil {
+ return errors.New("encoding system info parameters: " +
err.Error())
+ }
+ return nil
+}
+
+// WriteStatuses writes the Traffic Ops statuses to output.
+// Note this is identical to /api/1.x/statuses except it omits the
'{response:' wrapper.
+func WriteStatuses(cfg config.TCCfg, output io.Writer) error {
+ statuses, _, err := cfg.TOClient.GetStatuses()
+ if err != nil {
+ return errors.New("getting statuses: " + err.Error())
+ }
+ if err := json.NewEncoder(output).Encode(statuses); err != nil {
+ return errors.New("encoding statuses: " + err.Error())
+ }
+ return nil
+}
+
+// WriteUpdateStatus writes the Traffic Ops server update status to output.
+// Note this is identical to /api/1.x/servers/name/update_status except it
omits the '[]' wrapper.
+func WriteServerUpdateStatus(cfg config.TCCfg, output io.Writer) error {
+ status, _, unsupported, err :=
cfg.TOClientNew.GetServerUpdateStatus(tc.CacheName(cfg.CacheHostName))
+ if err == nil && unsupported {
+ log.Warnln("ORT newer than Traffic Ops, falling back to
previous API Delivery Services!")
+ status, _, err =
cfg.TOClient.GetServerUpdateStatus(tc.CacheName(cfg.CacheHostName))
+ }
+ if err != nil {
+ return errors.New("getting server update status: " +
err.Error())
+ }
+ if err := json.NewEncoder(output).Encode(status); err != nil {
+ return errors.New("encoding server update status: " +
err.Error())
+ }
+ return nil
+}
+
+// WriteORTServerPackages writes the packages for serverName to output.
+// Note this is identical to /ort/serverName/packages.
+func WritePackages(cfg config.TCCfg, output io.Writer) error {
+ packages, err := GetPackages(cfg)
+ if err != nil {
+ return errors.New("getting ORT server packages: " + err.Error())
+ }
+ if err := json.NewEncoder(output).Encode(packages); err != nil {
+ return errors.New("writing packages: " + err.Error())
+ }
+ return nil
+}
+
+func GetPackages(cfg config.TCCfg) ([]Package, error) {
+ server, _, err :=
cfg.TOClient.GetServerByHostName(string(cfg.CacheHostName))
+ if err != nil {
+ return nil, errors.New("getting server: " + err.Error())
+ } else if server.Profile == nil {
+ return nil, errors.New("getting server: nil profile")
+ }
+ params, _, err :=
cfg.TOClient.GetServerProfileParameters(*server.Profile)
+ if err != nil {
+ return nil, errors.New("getting server profile '" +
*server.Profile + "' parameters: " + err.Error())
+ }
+ packages := []Package{}
+ for _, param := range params {
+ if param.ConfigFile != atscfg.PackagesParamConfigFile {
+ continue
+ }
+ packages = append(packages, Package{Name: param.Name, Version:
param.Value})
+ }
+ return packages, nil
+}
+
+type Package struct {
+ Name string `json:"name"`
+ Version string `json:"version"`
+}
+
+// WriteChkconfig writes the chkconfig for cfg.CacheHostName to output.
+// Note this is identical to /ort/serverName/chkconfig.
+func WriteChkconfig(cfg config.TCCfg, output io.Writer) error {
+ chkconfig, err := GetChkconfig(cfg)
+ if err != nil {
+ return errors.New("getting chkconfig: " + err.Error())
+ }
+ if err := json.NewEncoder(output).Encode(chkconfig); err != nil {
+ return errors.New("writing chkconfig: " + err.Error())
+ }
+ return nil
+}
+
+func GetChkconfig(cfg config.TCCfg) ([]ChkConfigEntry, error) {
+ server, _, err :=
cfg.TOClient.GetServerByHostName(string(cfg.CacheHostName))
+ if err != nil {
+ return nil, errors.New("getting server: " + err.Error())
+ } else if server.Profile == nil {
+ return nil, errors.New("getting server: nil profile")
+ }
+ params, _, err :=
cfg.TOClient.GetServerProfileParameters(*server.Profile)
+ if err != nil {
+ return nil, errors.New("getting server profile '" +
*server.Profile + "' parameters: " + err.Error())
+ }
+ chkconfig := []ChkConfigEntry{}
+ for _, param := range params {
+ if param.ConfigFile != atscfg.ChkconfigParamConfigFile {
+ continue
+ }
+ chkconfig = append(chkconfig, ChkConfigEntry{Name: param.Name,
Val: param.Value})
+ }
+ return chkconfig, nil
+}
+
+type ChkConfigEntry struct {
+ Name string `json:"name"`
+ Val string `json:"value"`
+}
+
+// SetUpdateStatus sets the queue and reval status of serverName in Traffic
Ops.
+func SetUpdateStatus(cfg config.TCCfg, serverName tc.CacheName, queue bool,
revalPending bool) error {
+ reqInf, err :=
cfg.TOClientNew.C.SetUpdateServerStatuses(string(serverName), &queue,
&revalPending)
+ if err != nil && toreqnew.IsUnsupportedErr(err) {
+ err = setUpdateStatusLegacy(cfg, serverName, queue,
revalPending)
+ }
+ if err != nil {
+ return errors.New("setting update statuses (Traffic Ops '" +
toreq.MaybeIPStr(reqInf.RemoteAddr) + "'): " + err.Error())
+ }
+ return nil
+}
+
+// setUpdateStatusLegacy sets the queue and reval status of serverName in
Traffic Ops,
+// using the legacy pre-2.0 /update endpoint.
+func setUpdateStatusLegacy(cfg config.TCCfg, serverName tc.CacheName, queue
bool, revalPending bool) error {
+ path := `/update/` + string(serverName) + `?updated=` +
jsonBoolStr(queue) + `&reval_updated=` + jsonBoolStr(revalPending)
+ // C and RawRequest should generally never be used, but the alternatve
here is to manually get the cookie and do an http.Get. We need to hit a non-API
endpoint, no API endpoint exists for what we need.
+ resp, _, err := cfg.TOClient.C.RawRequest(http.MethodPost, path, nil)
+ if err != nil {
+ return errors.New("setting update statuses: " + err.Error())
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != 200 {
+ bodyBts, err := ioutil.ReadAll(resp.Body)
+ if err == nil {
+ return fmt.Errorf("Traffic Ops returned %v %v",
resp.StatusCode, string(bodyBts))
+ }
+ return fmt.Errorf("Traffic Ops returned %v (error reading
body)", resp.StatusCode)
+ }
+ return nil
+}
+
+func jsonBoolStr(b bool) string {
+ if b {
+ return `true`
+ }
+ return `false`
+}
diff --git a/traffic_ops_ort/to_requester/to_requester.go
b/traffic_ops_ort/to_requester/to_requester.go
new file mode 100644
index 0000000..ee55dda
--- /dev/null
+++ b/traffic_ops_ort/to_requester/to_requester.go
@@ -0,0 +1,134 @@
+/*
+Name
+ to_requester - ORT Traffic Ops Requestor
+
+Synopsis
+ to_requester [-hI] [-D value] [-d value] [-e value] [-H value] [-i
value] \
+ [-l value] [-P value] [-t value] [-u value] [-U value]
+
+Description
+ The to_requester is used get update status, package information, linux
+ chkconfig status, system info and status from Traffic Ops, see the
+ --get-data option. If no --get-data option is specified, the servers
+ system-info is fetched and returned.
+
+Options
+ -D, --get-data=value
+ non-config-file Traffic Ops Data to get. Valid values are
+ all, update-status, packages, chkconfig, system-info, and
+ statuses [all]
+ -d, --log-location-debug=value
+ Where to log debugs. May be a file path, stdout or stderr.
+ Default is no debug logging.
+ -e, --log-location-error=value
+ Where to log errors. May be a file path, stdout, or stderr.
+ Default is stderr.
+ -i, --log-location-info=value
+ Where to log infos. May be a file path, stdout or stderr.
+ Default is stderr.
+ -H, --cache-host-name=value
+ Host name of the cache to generate config for. Must be the
+ server host name in Traffic Ops, not a URL, and not the FQDN.
+ Defaults to the OS configured hostname.
+ -h, --help Print usage information and exit
+ -I, --traffic-ops-insecure
+ [true | false] ignore certificate errors from
Traffic Ops
+ -l, --login-dispersion=value
+ [seconds] wait a random number of seconds between 0 and
+ [seconds] before login to traffic ops, default 0
+ -P, --traffic-ops-password=value
+ Traffic Ops password. Required. May also be set with the
+ environment variable TO_PASS
+ -t, --traffic-ops-timeout-milliseconds=value
+ Timeout in milli-seconds for Traffic Ops requests, default
+ is 30000 [30000]
+ -u, --traffic-ops-url=value
+ Traffic Ops URL. Must be the full URL, including the scheme.
+ Required. May also be set with the environment variable
+ TO_URL
+ -U, --traffic-ops-user=value
+ Traffic Ops username. Required. May also be set with the
+ environment variable TO_USER
+*/
+
+package main
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import (
+ "errors"
+ "fmt"
+ "os"
+
+ "github.com/apache/trafficcontrol/lib/go-log"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/atstccfg/toreq"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/atstccfg/toreqnew"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/to_requester/config"
+ "github.com/apache/trafficcontrol/traffic_ops_ort/to_requester/getdata"
+)
+
+var (
+ cfg config.Cfg
+)
+
+func main() {
+ var err error
+
+ cfg, err = config.InitConfig()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "ERROR: %s\n", err.Error())
+ os.Exit(1)
+ } else {
+ log.Infoln("configuration initialized")
+ cfg.PrintConfig()
+ }
+
+ // login to traffic ops.
+ tccfg, err := toConnect()
+ if err != nil {
+ log.Errorf("%s\n", err)
+ os.Exit(2)
+ }
+ if tccfg.Cfg.GetData != "" {
+ if err := getdata.WriteData(*tccfg); err != nil {
+ log.Errorf("writing data: %s\n", err.Error())
+ os.Exit(3)
+ }
+ }
+}
+
+/*
+ * connect and login to traffic ops
+ */
+func toConnect() (*config.TCCfg, error) {
+ _toClient, err := toreq.New(cfg.TOURL, cfg.TOUser, cfg.TOPass,
cfg.TOInsecure, cfg.TOTimeoutMS, config.UserAgent)
+ if err != nil {
+ return nil, errors.New("failed to connect to traffic ops: " +
err.Error())
+ }
+ _toClientNew, err := toreqnew.New(_toClient.Cookies(cfg.TOURL),
cfg.TOURL, cfg.TOUser, cfg.TOPass, cfg.TOInsecure, cfg.TOTimeoutMS,
config.UserAgent)
+
+ tccfg := config.TCCfg{
+ Cfg: cfg,
+ TOClient: _toClient,
+ TOClientNew: _toClientNew,
+ }
+
+ return &tccfg, nil
+}