This is an automated email from the ASF dual-hosted git repository.
neuman 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 4de0a00 Fix ORT atstccfg to allow using new features in the latest
Traffic Ops (#4534)
4de0a00 is described below
commit 4de0a001a5b03d066ebf69e8ef0725c14244ef76
Author: Robert O Butts <[email protected]>
AuthorDate: Tue Mar 31 09:36:23 2020 -0600
Fix ORT atstccfg to allow using new features in the latest Traffic Ops
(#4534)
* Add ORT atstccfg TO latest version client
Adds a client of the latest Traffic Ops version, and refactors the
existing vendored client, so both can be used at once.
Includes an idiom of using the latest and falling back to vendored.
Also includes an example of the latest client getting Delivery
Services, and falling back to the vendored if the TO isn't the latest.
This isn't actually necessary right now, but it's likely to be very
shortly, and it serves as an example of the idiom for future dev.
* Add ORT/atstcfg script,readme for updating client
---
traffic_ops/ort/atstccfg/README.md | 8 +
traffic_ops/ort/atstccfg/atstccfg.go | 7 +-
traffic_ops/ort/atstccfg/cfgfile/cfgfile.go | 41 +--
traffic_ops/ort/atstccfg/config/config.go | 12 +-
traffic_ops/ort/atstccfg/getdata/getdata.go | 20 +-
traffic_ops/ort/atstccfg/toreq/toreq.go | 198 +++++++-------
traffic_ops/ort/atstccfg/toreq/trafficops.go | 210 ---------------
.../github.com/apache/trafficcontrol/LICENSE | 0
.../github.com/apache/trafficcontrol/VERSION | 0
.../github.com/apache/trafficcontrol/changeset.txt | 0
.../trafficcontrol/traffic_ops/client/README.md | 0
.../trafficcontrol/traffic_ops/client/about.go | 0
.../trafficcontrol/traffic_ops/client/asn.go | 0
.../trafficcontrol/traffic_ops/client/atsconfig.go | 0
.../traffic_ops/client/cachegroup.go | 0
.../traffic_ops/client/cachegroup_parameters.go | 0
.../trafficcontrol/traffic_ops/client/cdn.go | 0
.../traffic_ops/client/cdn_domains.go | 0
.../traffic_ops/client/cdnfederations.go | 0
.../traffic_ops/client/coordinate.go | 0
.../trafficcontrol/traffic_ops/client/crconfig.go | 0
.../traffic_ops/client/deliveryservice.go | 0
.../client/deliveryservice_endpoints.go | 0
.../client/deliveryservice_request_comments.go | 0
.../traffic_ops/client/deliveryservice_requests.go | 0
.../deliveryservices_required_capabilities.go | 0
.../traffic_ops/client/deliveryserviceserver.go | 0
.../trafficcontrol/traffic_ops/client/division.go | 0
.../trafficcontrol/traffic_ops/client/dsuser.go | 0
.../trafficcontrol/traffic_ops/client/endpoints.go | 0
.../traffic_ops/client/federation.go | 0
.../traffic_ops/client/federation_resolver.go | 0
.../trafficcontrol/traffic_ops/client/hardware.go | 0
.../trafficcontrol/traffic_ops/client/iso.go | 0
.../trafficcontrol/traffic_ops/client/job.go | 0
.../trafficcontrol/traffic_ops/client/log.go | 0
.../trafficcontrol/traffic_ops/client/origin.go | 0
.../trafficcontrol/traffic_ops/client/parameter.go | 0
.../traffic_ops/client/phys_location.go | 0
.../trafficcontrol/traffic_ops/client/ping.go | 0
.../trafficcontrol/traffic_ops/client/profile.go | 0
.../traffic_ops/client/profile_parameter.go | 0
.../trafficcontrol/traffic_ops/client/region.go | 0
.../trafficcontrol/traffic_ops/client/role.go | 0
.../trafficcontrol/traffic_ops/client/server.go | 0
.../client/server_server_capabilities.go | 0
.../traffic_ops/client/server_update_status.go | 0
.../traffic_ops/client/servercapability.go | 0
.../traffic_ops/client/servercheck.go | 0
.../traffic_ops/client/serversstatus.go | 0
.../trafficcontrol/traffic_ops/client/session.go | 0
.../traffic_ops/client/staticdnsentry.go | 0
.../traffic_ops/client/stats_summary.go | 0
.../trafficcontrol/traffic_ops/client/status.go | 0
.../trafficcontrol/traffic_ops/client/steering.go | 0
.../traffic_ops/client/steeringtarget.go | 0
.../trafficcontrol/traffic_ops/client/tenant.go | 0
.../traffic_ops/client/tenant_endpoints.go | 0
.../traffic_ops/client/toextension.go | 0
.../traffic_ops/client/traffic_monitor.go | 0
.../traffic_ops/client/traffic_stats.go | 0
.../trafficcontrol/traffic_ops/client/type.go | 0
.../trafficcontrol/traffic_ops/client/update.go | 0
.../trafficcontrol/traffic_ops/client/user.go | 0
.../trafficcontrol/traffic_ops/client/util.go | 0
traffic_ops/ort/atstccfg/toreqnew/toreqnew.go | 97 +++++++
traffic_ops/ort/atstccfg/torequtil/torequtil.go | 90 +++++++
.../ort/atstccfg/torequtil/torequtil_test.go | 70 +++++
.../atstccfg/update-to-client/update-to-client.go | 290 +++++++++++++++++++++
69 files changed, 706 insertions(+), 337 deletions(-)
diff --git a/traffic_ops/ort/atstccfg/README.md
b/traffic_ops/ort/atstccfg/README.md
index ddaada3..ccecdc0 100644
--- a/traffic_ops/ort/atstccfg/README.md
+++ b/traffic_ops/ort/atstccfg/README.md
@@ -45,3 +45,11 @@ The available options are:
-w WARNING_LOCATION, --log-location-warning WARNING_LOCATION The file
location to which to log warnings. Respects the special string constants of
github.com/apache/trafficcontrol/lib/go-log. Default: 'stderr'
```
atstccfg caches generated files in /tmp/atstccfg_cache/ for re-use.
+
+# Development
+
+## Updating for new Traffic Control Versions
+
+After a new Traffic Control release, the Traffic Ops client from the new
release branch should be vendored at `toreq/vendor`, and all usages of
`config.TOClientNew` should be changed to `config.TOClient`.
+
+There's a script to do this at
`ort/atstccfg/update-to-client/update-to-client.go`. Run the script with no
arguments for usage information.
diff --git a/traffic_ops/ort/atstccfg/atstccfg.go
b/traffic_ops/ort/atstccfg/atstccfg.go
index 4246aea..ee9ab87 100644
--- a/traffic_ops/ort/atstccfg/atstccfg.go
+++ b/traffic_ops/ort/atstccfg/atstccfg.go
@@ -58,6 +58,7 @@ import (
"github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/getdata"
"github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/plugin"
"github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/toreq"
+ "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/toreqnew"
)
func main() {
@@ -75,12 +76,16 @@ func main() {
plugins := plugin.Get(cfg)
plugins.OnStartup(plugin.StartupData{Cfg: cfg})
- tccfg, err := toreq.GetTCCfg(cfg)
+ toClient, err := toreq.New(cfg.TOURL, cfg.TOUser, cfg.TOPass,
cfg.TOInsecure, cfg.TOTimeout, config.UserAgent)
if err != nil {
log.Errorln(err)
os.Exit(config.ExitCodeErrGeneric)
}
+ toClientNew, err := toreqnew.New(toClient.Cookies(cfg.TOURL),
cfg.TOURL, cfg.TOUser, cfg.TOPass, cfg.TOInsecure, cfg.TOTimeout,
config.UserAgent)
+
+ tccfg := config.TCCfg{Cfg: cfg, TOClient: toClient, TOClientNew:
toClientNew}
+
if tccfg.GetData != "" {
if err := getdata.WriteData(tccfg); err != nil {
log.Errorln("writing data: " + err.Error())
diff --git a/traffic_ops/ort/atstccfg/cfgfile/cfgfile.go
b/traffic_ops/ort/atstccfg/cfgfile/cfgfile.go
index f825301..40b1aaa 100644
--- a/traffic_ops/ort/atstccfg/cfgfile/cfgfile.go
+++ b/traffic_ops/ort/atstccfg/cfgfile/cfgfile.go
@@ -47,7 +47,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
serversF := func() error {
defer func(start time.Time) { log.Infof("serversF took %v\n",
time.Since(start)) }(time.Now())
// TODO TOAPI add /servers?cdn=1 query param
- servers, err := toreq.GetServers(cfg)
+ servers, err := cfg.TOClient.GetServers()
if err != nil {
return errors.New("getting servers: " + err.Error())
}
@@ -69,7 +69,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
sslF := func() error {
defer func(start time.Time) { log.Infof("sslF took
%v\n", time.Since(start)) }(time.Now())
- keys, err := toreq.GetCDNSSLKeys(cfg,
tc.CDNName(server.CDNName))
+ keys, err :=
cfg.TOClient.GetCDNSSLKeys(tc.CDNName(server.CDNName))
if err != nil {
return errors.New("getting cdn '" +
server.CDNName + "': " + err.Error())
}
@@ -78,7 +78,12 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
dsF := func() error {
defer func(start time.Time) { log.Infof("dsF took
%v\n", time.Since(start)) }(time.Now())
- dses, err := toreq.GetCDNDeliveryServices(cfg,
server.CDNID)
+
+ dses, unsupported, err :=
cfg.TOClientNew.GetCDNDeliveryServices(server.CDNID)
+ if err == nil && unsupported {
+ log.Warnln("Traffic Ops newer than ORT, falling
back to previous API Delivery Services!")
+ dses, err =
cfg.TOClient.GetCDNDeliveryServices(server.CDNID)
+ }
if err != nil {
return errors.New("getting delivery services: "
+ err.Error())
}
@@ -95,7 +100,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
if ds.SigningAlgorithm == nil ||
*ds.SigningAlgorithm != tc.SigningAlgorithmURISigning {
continue
}
- keys, err :=
toreq.GetURISigningKeys(cfg, *ds.XMLID)
+ keys, err :=
cfg.TOClient.GetURISigningKeys(*ds.XMLID)
if err != nil {
if
strings.Contains(strings.ToLower(err.Error()), "not found") {
log.Errorln("Delivery
service '" + *ds.XMLID + "' is uri_signing, but keys were not found! Skipping!")
@@ -121,7 +126,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
if ds.SigningAlgorithm == nil ||
*ds.SigningAlgorithm != tc.SigningAlgorithmURLSig {
continue
}
- keys, err := toreq.GetURLSigKeys(cfg,
*ds.XMLID)
+ keys, err :=
cfg.TOClient.GetURLSigKeys(*ds.XMLID)
if err != nil {
if
strings.Contains(strings.ToLower(err.Error()), "not found") {
log.Errorln("Delivery
service '" + *ds.XMLID + "' is url_sig, but keys were not found! Skipping!: " +
err.Error())
@@ -144,7 +149,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
serverParamsF := func() error {
defer func(start time.Time) { log.Infof("serverParamsF
took %v\n", time.Since(start)) }(time.Now())
- params, err := toreq.GetServerProfileParameters(cfg,
server.Profile)
+ params, err :=
cfg.TOClient.GetServerProfileParameters(server.Profile)
if err != nil {
return errors.New("getting server profile '" +
server.Profile + "' parameters: " + err.Error())
} else if len(params) == 0 {
@@ -155,7 +160,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
cdnF := func() error {
defer func(start time.Time) { log.Infof("cdnF took
%v\n", time.Since(start)) }(time.Now())
- cdn, err := toreq.GetCDN(cfg,
tc.CDNName(server.CDNName))
+ cdn, err :=
cfg.TOClient.GetCDN(tc.CDNName(server.CDNName))
if err != nil {
return errors.New("getting cdn '" +
server.CDNName + "': " + err.Error())
}
@@ -164,7 +169,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
profileF := func() error {
defer func(start time.Time) { log.Infof("profileF took
%v\n", time.Since(start)) }(time.Now())
- profile, err := toreq.GetProfileByName(cfg,
server.Profile)
+ profile, err :=
cfg.TOClient.GetProfileByName(server.Profile)
if err != nil {
return errors.New("getting profile '" +
server.Profile + "': " + err.Error())
}
@@ -180,7 +185,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
cgF := func() error {
defer func(start time.Time) { log.Infof("cfF took %v\n",
time.Since(start)) }(time.Now())
- cacheGroups, err := toreq.GetCacheGroups(cfg)
+ cacheGroups, err := cfg.TOClient.GetCacheGroups()
if err != nil {
return errors.New("getting cachegroups: " + err.Error())
}
@@ -189,7 +194,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
globalParamsF := func() error {
defer func(start time.Time) { log.Infof("globalParamsF took
%v\n", time.Since(start)) }(time.Now())
- globalParams, err := toreq.GetGlobalParameters(cfg)
+ globalParams, err := cfg.TOClient.GetGlobalParameters()
if err != nil {
return errors.New("getting global parameters: " +
err.Error())
}
@@ -199,7 +204,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
scopeParamsF := func() error {
defer func(start time.Time) { log.Infof("scopeParamsF took
%v\n", time.Since(start)) }(time.Now())
- scopeParams, err := toreq.GetParametersByName(cfg, "scope")
+ scopeParams, err := cfg.TOClient.GetParametersByName("scope")
if err != nil {
return errors.New("getting scope parameters: " +
err.Error())
}
@@ -208,7 +213,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
dssF := func() error {
defer func(start time.Time) { log.Infof("dssF took %v\n",
time.Since(start)) }(time.Now())
- dss, err := toreq.GetDeliveryServiceServers(cfg, nil, nil)
+ dss, err := cfg.TOClient.GetDeliveryServiceServers(nil, nil)
if err != nil {
return errors.New("getting delivery service servers: "
+ err.Error())
}
@@ -217,7 +222,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
jobsF := func() error {
defer func(start time.Time) { log.Infof("jobsF took %v\n",
time.Since(start)) }(time.Now())
- jobs, err := toreq.GetJobs(cfg) // TODO add cdn query param to
jobs endpoint
+ jobs, err := cfg.TOClient.GetJobs() // TODO add cdn query param
to jobs endpoint
if err != nil {
return errors.New("getting jobs: " + err.Error())
}
@@ -226,7 +231,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
capsF := func() error {
defer func(start time.Time) { log.Infof("capsF took %v\n",
time.Since(start)) }(time.Now())
- caps, err := toreq.GetServerCapabilitiesByID(cfg, nil) // TODO
change to not take a param; it doesn't use it to request TO anyway.
+ caps, err := cfg.TOClient.GetServerCapabilitiesByID(nil) //
TODO change to not take a param; it doesn't use it to request TO anyway.
if err != nil {
log.Errorln("Server Capabilities error, skipping!")
// return errors.New("getting server caps from Traffic
Ops: " + err.Error())
@@ -237,7 +242,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
dsCapsF := func() error {
defer func(start time.Time) { log.Infof("dscapsF took %v\n",
time.Since(start)) }(time.Now())
- caps, err :=
toreq.GetDeliveryServiceRequiredCapabilitiesByID(cfg, nil)
+ caps, err :=
cfg.TOClient.GetDeliveryServiceRequiredCapabilitiesByID(nil)
if err != nil {
log.Errorln("DS Required Capabilities error, skipping!")
// return errors.New("getting DS required capabilities:
" + err.Error())
@@ -248,7 +253,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
dsrF := func() error {
defer func(start time.Time) { log.Infof("dsrF took %v\n",
time.Since(start)) }(time.Now())
- dsr, err := toreq.GetDeliveryServiceRegexes(cfg)
+ dsr, err := cfg.TOClient.GetDeliveryServiceRegexes()
if err != nil {
return errors.New("getting delivery service regexes: "
+ err.Error())
}
@@ -257,7 +262,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
cacheKeyParamsF := func() error {
defer func(start time.Time) { log.Infof("cacheKeyParamsF took
%v\n", time.Since(start)) }(time.Now())
- params, err := toreq.GetConfigFileParameters(cfg,
atscfg.CacheKeyParameterConfigFile)
+ params, err :=
cfg.TOClient.GetConfigFileParameters(atscfg.CacheKeyParameterConfigFile)
if err != nil {
return errors.New("getting cache key parameters: " +
err.Error())
}
@@ -266,7 +271,7 @@ func GetTOData(cfg config.TCCfg) (*config.TOData, error) {
}
parentConfigParamsF := func() error {
defer func(start time.Time) { log.Infof("parentConfigParamsF
took %v\n", time.Since(start)) }(time.Now())
- parentConfigParams, err := toreq.GetConfigFileParameters(cfg,
"parent.config") // TODO make const in lib/go-atscfg
+ parentConfigParams, err :=
cfg.TOClient.GetConfigFileParameters("parent.config") // TODO make const in
lib/go-atscfg
if err != nil {
return errors.New("getting parent.config parameters: "
+ err.Error())
}
diff --git a/traffic_ops/ort/atstccfg/config/config.go
b/traffic_ops/ort/atstccfg/config/config.go
index f6860cb..1265714 100644
--- a/traffic_ops/ort/atstccfg/config/config.go
+++ b/traffic_ops/ort/atstccfg/config/config.go
@@ -22,7 +22,6 @@ package config
import (
"errors"
"fmt"
- "math"
"net/url"
"os"
"strings"
@@ -31,7 +30,8 @@ import (
"github.com/apache/trafficcontrol/lib/go-atscfg"
"github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
- toclient "github.com/apache/trafficcontrol/traffic_ops/client"
+ "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/toreq"
+ "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/toreqnew"
flag "github.com/ogier/pflag"
)
@@ -68,7 +68,8 @@ type Cfg struct {
type TCCfg struct {
Cfg
- TOClient **toclient.Session
+ TOClient *toreq.TOClient
+ TOClientNew *toreqnew.TOClient
}
func (cfg Cfg) ErrorLog() log.LogLocation { return
log.LogLocation(cfg.LogLocationErr) }
@@ -194,11 +195,6 @@ func ValidateURL(u *url.URL) error {
return nil
}
-func RetryBackoffSeconds(currentRetry int) int {
- // TODO make configurable?
- return int(math.Pow(2.0, float64(currentRetry)))
-}
-
type ATSConfigFile struct {
tc.ATSConfigMetaDataConfigFile
Text string
diff --git a/traffic_ops/ort/atstccfg/getdata/getdata.go
b/traffic_ops/ort/atstccfg/getdata/getdata.go
index cae65c3..3923e73 100644
--- a/traffic_ops/ort/atstccfg/getdata/getdata.go
+++ b/traffic_ops/ort/atstccfg/getdata/getdata.go
@@ -35,7 +35,6 @@ import (
"github.com/apache/trafficcontrol/lib/go-log"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/config"
- "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/toreq"
)
func GetDataFuncs() map[string]func(config.TCCfg, io.Writer) error {
@@ -83,7 +82,7 @@ const SystemInfoParamConfigFile = `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 := toreq.GetConfigFileParameters(cfg,
SystemInfoParamConfigFile)
+ paramArr, err :=
cfg.TOClient.GetConfigFileParameters(SystemInfoParamConfigFile)
if err != nil {
return errors.New("getting system info parameters: " +
err.Error())
}
@@ -100,7 +99,7 @@ func WriteSystemInfo(cfg config.TCCfg, output io.Writer)
error {
// 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 := toreq.GetStatuses(cfg)
+ statuses, err := cfg.TOClient.GetStatuses()
if err != nil {
return errors.New("getting statuses: " + err.Error())
}
@@ -113,7 +112,7 @@ func WriteStatuses(cfg config.TCCfg, output io.Writer)
error {
// 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, err := toreq.GetServerUpdateStatus(cfg)
+ status, err :=
cfg.TOClient.GetServerUpdateStatus(tc.CacheName(cfg.CacheHostName))
if err != nil {
return errors.New("getting server update status: " +
err.Error())
}
@@ -137,11 +136,11 @@ func WritePackages(cfg config.TCCfg, output io.Writer)
error {
}
func GetPackages(cfg config.TCCfg) ([]atscfg.Package, error) {
- server, err := toreq.GetServerByHostName(cfg, string(cfg.CacheHostName))
+ server, err :=
cfg.TOClient.GetServerByHostName(string(cfg.CacheHostName))
if err != nil {
return nil, errors.New("getting server: " + err.Error())
}
- params, err := toreq.GetServerProfileParameters(cfg, server.Profile)
+ params, err := cfg.TOClient.GetServerProfileParameters(server.Profile)
if err != nil {
return nil, errors.New("getting server profile '" +
server.Profile + "' parameters: " + err.Error())
}
@@ -169,11 +168,11 @@ func WriteChkconfig(cfg config.TCCfg, output io.Writer)
error {
}
func GetChkconfig(cfg config.TCCfg) ([]atscfg.ChkConfigEntry, error) {
- server, err := toreq.GetServerByHostName(cfg, string(cfg.CacheHostName))
+ server, err :=
cfg.TOClient.GetServerByHostName(string(cfg.CacheHostName))
if err != nil {
return nil, errors.New("getting server: " + err.Error())
}
- params, err := toreq.GetServerProfileParameters(cfg, server.Profile)
+ params, err := cfg.TOClient.GetServerProfileParameters(server.Profile)
if err != nil {
return nil, errors.New("getting server profile '" +
server.Profile + "' parameters: " + err.Error())
}
@@ -191,8 +190,9 @@ func GetChkconfig(cfg config.TCCfg)
([]atscfg.ChkConfigEntry, error) {
func SetUpdateStatus(cfg config.TCCfg, serverName tc.CacheName, queue bool,
revalPending bool) error {
// TODO change this to an API path, when one exists
path := `/update/` + string(serverName) + `?updated=` +
jsonBoolStr(queue) + `&reval_updated=` + jsonBoolStr(revalPending)
- // 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).RawRequest(http.MethodPost, path, nil)
+ // 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.
+ // TODO move to a func in TOClient?
+ resp, _, err := cfg.TOClient.C.RawRequest(http.MethodPost, path, nil)
if err != nil {
return errors.New("setting update statuses: " + err.Error())
}
diff --git a/traffic_ops/ort/atstccfg/toreq/toreq.go
b/traffic_ops/ort/atstccfg/toreq/toreq.go
index 7262dd8..69f74c4 100644
--- a/traffic_ops/ort/atstccfg/toreq/toreq.go
+++ b/traffic_ops/ort/atstccfg/toreq/toreq.go
@@ -1,3 +1,9 @@
+// toreqnew implements a Traffic Ops client vendored one version back.
+//
+// This should be used for all requests, unless they require an endpoint or
field added in the latest version.
+//
+// If a feature in the latest Traffic Ops is required, toreqnew should be used
with a fallback to this client if the Traffic Ops is not the latest (which can
be determined by the bool returned by all toreqnew.TOClient funcs).
+//
package toreq
/*
@@ -22,22 +28,61 @@ package toreq
import (
"encoding/base64"
"errors"
+ "net"
+ "net/url"
"strconv"
- "strings"
"time"
"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/lib/go-util"
- "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/config"
+ toclient "github.com/apache/trafficcontrol/traffic_ops/client"
+ "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/torequtil"
)
-func GetProfileByName(cfg config.TCCfg, profileName string) (tc.Profile,
error) {
+type TOClient struct {
+ C *toclient.Session
+ NumRetries int
+}
+
+// New logs into Traffic Ops, returning the TOClient which contains the
logged-in client.
+func New(url *url.URL, user string, pass string, insecure bool, timeout
time.Duration, userAgent string) (*TOClient, error) {
+ log.Infoln("URL: '" + url.String() + "' User: '" + user + "' Pass len:
'" + strconv.Itoa(len(pass)) + "'")
+
+ toFQDN := url.Scheme + "://" + url.Host
+ log.Infoln("TO FQDN: '" + toFQDN + "'")
+ log.Infoln("TO URL: '" + url.String() + "'")
+
+ toClient, toIP, err := toclient.LoginWithAgent(toFQDN, user, pass,
insecure, userAgent, false, timeout)
+ if err != nil {
+ return nil, errors.New("Logging in to Traffic Ops '" +
MaybeIPStr(toIP) + "': " + err.Error())
+ }
+
+ return &TOClient{C: toClient}, nil
+}
+
+// Cookies returns the HTTP session cookies from the client.
+// It does not do any kind of validation, but assumes the HTTP cookies exist
from a prior login and are valid for a Traffic Ops session.
+// The url is the Traffic Ops URL, and should match this client's Traffic Ops
URL, and the URL of the new client this session cookie is presumably being
fetched for.
+func (cl *TOClient) Cookies(url *url.URL) string {
+ return torequtil.CookiesToString(cl.C.Client.Jar.Cookies(url))
+}
+
+// MaybeIPStr returns the addr string if it isn't nil, or the empty string if
it is.
+// This is intended for logging, to allow logging with one line, whether addr
is nil or not.
+func MaybeIPStr(addr net.Addr) string {
+ if addr != nil {
+ return addr.String()
+ }
+ return ""
+}
+
+func (cl *TOClient) GetProfileByName(profileName string) (tc.Profile, error) {
profile := tc.Profile{}
- err := GetRetry(cfg, "profile_"+profileName, &profile, func(obj
interface{}) error {
- toProfiles, reqInf, err :=
(*cfg.TOClient).GetProfileByName(profileName)
+ err := torequtil.GetRetry(cl.NumRetries, "profile_"+profileName,
&profile, func(obj interface{}) error {
+ toProfiles, reqInf, err := cl.C.GetProfileByName(profileName)
if err != nil {
return errors.New("getting profile '" + profileName +
"' from Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -56,10 +101,10 @@ func GetProfileByName(cfg config.TCCfg, profileName
string) (tc.Profile, error)
return profile, nil
}
-func GetGlobalParameters(cfg config.TCCfg) ([]tc.Parameter, error) {
+func (cl *TOClient) GetGlobalParameters() ([]tc.Parameter, error) {
globalParams := []tc.Parameter{}
- err := GetRetry(cfg, "profile_global_parameters", &globalParams,
func(obj interface{}) error {
- toParams, reqInf, err :=
(*cfg.TOClient).GetParametersByProfileName(tc.GlobalProfileName)
+ err := torequtil.GetRetry(cl.NumRetries, "profile_global_parameters",
&globalParams, func(obj interface{}) error {
+ toParams, reqInf, err :=
cl.C.GetParametersByProfileName(tc.GlobalProfileName)
if err != nil {
return errors.New("getting global profile '" +
tc.GlobalProfileName + "' parameters from Traffic Ops '" +
MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -74,6 +119,7 @@ func GetGlobalParameters(cfg config.TCCfg) ([]tc.Parameter,
error) {
}
func GetTOToolNameAndURL(globalParams []tc.Parameter) (string, string) {
+ // TODO move somewhere generic
toToolName := ""
toURL := ""
for _, param := range globalParams {
@@ -96,10 +142,10 @@ func GetTOToolNameAndURL(globalParams []tc.Parameter)
(string, string) {
return toToolName, toURL
}
-func GetServers(cfg config.TCCfg) ([]tc.Server, error) {
+func (cl *TOClient) GetServers() ([]tc.Server, error) {
servers := []tc.Server{}
- err := GetRetry(cfg, "servers", &servers, func(obj interface{}) error {
- toServers, reqInf, err := (*cfg.TOClient).GetServers()
+ err := torequtil.GetRetry(cl.NumRetries, "servers", &servers, func(obj
interface{}) error {
+ toServers, reqInf, err := cl.C.GetServers()
if err != nil {
return errors.New("getting servers from Traffic Ops '"
+ MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -113,10 +159,10 @@ func GetServers(cfg config.TCCfg) ([]tc.Server, error) {
return servers, nil
}
-func GetServerByHostName(cfg config.TCCfg, serverHostName string) (tc.Server,
error) {
+func (cl *TOClient) GetServerByHostName(serverHostName string) (tc.Server,
error) {
server := tc.Server{}
- err := GetRetry(cfg, "server-name-"+serverHostName, &server, func(obj
interface{}) error {
- toServers, reqInf, err :=
(*cfg.TOClient).GetServerByHostName(serverHostName)
+ err := torequtil.GetRetry(cl.NumRetries, "server-name-"+serverHostName,
&server, func(obj interface{}) error {
+ toServers, reqInf, err :=
cl.C.GetServerByHostName(serverHostName)
if err != nil {
return errors.New("getting server name '" +
serverHostName + "' from Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': "
+ err.Error())
} else if len(toServers) < 1 {
@@ -132,10 +178,10 @@ func GetServerByHostName(cfg config.TCCfg, serverHostName
string) (tc.Server, er
return server, nil
}
-func GetCacheGroups(cfg config.TCCfg) ([]tc.CacheGroupNullable, error) {
+func (cl *TOClient) GetCacheGroups() ([]tc.CacheGroupNullable, error) {
cacheGroups := []tc.CacheGroupNullable{}
- err := GetRetry(cfg, "cachegroups", &cacheGroups, func(obj interface{})
error {
- toCacheGroups, reqInf, err :=
(*cfg.TOClient).GetCacheGroupsNullable()
+ err := torequtil.GetRetry(cl.NumRetries, "cachegroups", &cacheGroups,
func(obj interface{}) error {
+ toCacheGroups, reqInf, err := cl.C.GetCacheGroupsNullable()
if err != nil {
return errors.New("getting cachegroups from Traffic Ops
'" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -154,7 +200,7 @@ func GetCacheGroups(cfg config.TCCfg)
([]tc.CacheGroupNullable, error) {
// If your use case is more efficient to only get the needed objects, for
example if you're frequently requesting one file, set this false to get and
cache the specific needed delivery services and servers.
const DeliveryServiceServersAlwaysGetAll = true
-func GetDeliveryServiceServers(cfg config.TCCfg, dsIDs []int, serverIDs []int)
([]tc.DeliveryServiceServer, error) {
+func (cl *TOClient) GetDeliveryServiceServers(dsIDs []int, serverIDs []int)
([]tc.DeliveryServiceServer, error) {
const sortIDsInHash = true
serverIDsStr := ""
@@ -173,9 +219,9 @@ func GetDeliveryServiceServers(cfg config.TCCfg, dsIDs
[]int, serverIDs []int) (
}
dsServers := []tc.DeliveryServiceServer{}
- err := GetRetry(cfg,
"deliveryservice_servers_s"+serverIDsStr+"_d_"+dsIDsStr, &dsServers, func(obj
interface{}) error {
+ err := torequtil.GetRetry(cl.NumRetries,
"deliveryservice_servers_s"+serverIDsStr+"_d_"+dsIDsStr, &dsServers, func(obj
interface{}) error {
const noLimit = 999999 // TODO add "no limit" param to DSS
endpoint
- toDSS, reqInf, err :=
(*cfg.TOClient).GetDeliveryServiceServersWithLimits(noLimit, dsIDsToFetch,
sIDsToFetch)
+ toDSS, reqInf, err :=
cl.C.GetDeliveryServiceServersWithLimits(noLimit, dsIDsToFetch, sIDsToFetch)
if err != nil {
return errors.New("getting delivery service servers
from Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -219,10 +265,10 @@ func GetDeliveryServiceServers(cfg config.TCCfg, dsIDs
[]int, serverIDs []int) (
return filteredDSServers, nil
}
-func GetServerProfileParameters(cfg config.TCCfg, profileName string)
([]tc.Parameter, error) {
+func (cl *TOClient) GetServerProfileParameters(profileName string)
([]tc.Parameter, error) {
serverProfileParameters := []tc.Parameter{}
- err := GetRetry(cfg, "profile_"+profileName+"_parameters",
&serverProfileParameters, func(obj interface{}) error {
- toParams, reqInf, err :=
(*cfg.TOClient).GetParametersByProfileName(profileName)
+ err := torequtil.GetRetry(cl.NumRetries,
"profile_"+profileName+"_parameters", &serverProfileParameters, func(obj
interface{}) error {
+ toParams, reqInf, err :=
cl.C.GetParametersByProfileName(profileName)
if err != nil {
return errors.New("getting server profile '" +
profileName + "' parameters from Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr)
+ "': " + err.Error())
}
@@ -236,10 +282,10 @@ func GetServerProfileParameters(cfg config.TCCfg,
profileName string) ([]tc.Para
return serverProfileParameters, nil
}
-func GetCDNDeliveryServices(cfg config.TCCfg, cdnID int)
([]tc.DeliveryServiceNullable, error) {
+func (cl *TOClient) GetCDNDeliveryServices(cdnID int)
([]tc.DeliveryServiceNullable, error) {
deliveryServices := []tc.DeliveryServiceNullable{}
- err := GetRetry(cfg, "cdn_"+strconv.Itoa(cdnID)+"_deliveryservices",
&deliveryServices, func(obj interface{}) error {
- toDSes, reqInf, err :=
(*cfg.TOClient).GetDeliveryServicesByCDNID(cdnID)
+ err := torequtil.GetRetry(cl.NumRetries,
"cdn_"+strconv.Itoa(cdnID)+"_deliveryservices", &deliveryServices, func(obj
interface{}) error {
+ toDSes, reqInf, err := cl.C.GetDeliveryServicesByCDNID(cdnID)
if err != nil {
return errors.New("getting delivery services from
Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -253,10 +299,10 @@ func GetCDNDeliveryServices(cfg config.TCCfg, cdnID int)
([]tc.DeliveryServiceNu
return deliveryServices, nil
}
-func GetConfigFileParameters(cfg config.TCCfg, configFile string)
([]tc.Parameter, error) {
+func (cl *TOClient) GetConfigFileParameters(configFile string)
([]tc.Parameter, error) {
params := []tc.Parameter{}
- err := GetRetry(cfg, "config_file_"+configFile+"_parameters", ¶ms,
func(obj interface{}) error {
- toParams, reqInf, err :=
(*cfg.TOClient).GetParameterByConfigFile(configFile)
+ err := torequtil.GetRetry(cl.NumRetries,
"config_file_"+configFile+"_parameters", ¶ms, func(obj interface{}) error {
+ toParams, reqInf, err :=
cl.C.GetParameterByConfigFile(configFile)
if err != nil {
return errors.New("getting delivery services from
Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -270,10 +316,10 @@ func GetConfigFileParameters(cfg config.TCCfg, configFile
string) ([]tc.Paramete
return params, nil
}
-func GetCDN(cfg config.TCCfg, cdnName tc.CDNName) (tc.CDN, error) {
+func (cl *TOClient) GetCDN(cdnName tc.CDNName) (tc.CDN, error) {
cdn := tc.CDN{}
- err := GetRetry(cfg, "cdn_"+string(cdnName), &cdn, func(obj
interface{}) error {
- toCDNs, reqInf, err :=
(*cfg.TOClient).GetCDNByName(string(cdnName))
+ err := torequtil.GetRetry(cl.NumRetries, "cdn_"+string(cdnName), &cdn,
func(obj interface{}) error {
+ toCDNs, reqInf, err := cl.C.GetCDNByName(string(cdnName))
if err != nil {
return errors.New("getting cdn from Traffic Ops '" +
MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -290,10 +336,10 @@ func GetCDN(cfg config.TCCfg, cdnName tc.CDNName)
(tc.CDN, error) {
return cdn, nil
}
-func GetURLSigKeys(cfg config.TCCfg, dsName string) (tc.URLSigKeys, error) {
+func (cl *TOClient) GetURLSigKeys(dsName string) (tc.URLSigKeys, error) {
keys := tc.URLSigKeys{}
- err := GetRetry(cfg, "urlsigkeys_"+string(dsName), &keys, func(obj
interface{}) error {
- toKeys, reqInf, err :=
(*cfg.TOClient).GetDeliveryServiceURLSigKeys(dsName)
+ err := torequtil.GetRetry(cl.NumRetries, "urlsigkeys_"+string(dsName),
&keys, func(obj interface{}) error {
+ toKeys, reqInf, err := cl.C.GetDeliveryServiceURLSigKeys(dsName)
if err != nil {
return errors.New("getting url sig keys from Traffic
Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -307,10 +353,10 @@ func GetURLSigKeys(cfg config.TCCfg, dsName string)
(tc.URLSigKeys, error) {
return keys, nil
}
-func GetURISigningKeys(cfg config.TCCfg, dsName string) ([]byte, error) {
+func (cl *TOClient) GetURISigningKeys(dsName string) ([]byte, error) {
keys := []byte{}
- err := GetRetry(cfg, "urisigningkeys_"+string(dsName), &keys, func(obj
interface{}) error {
- toKeys, reqInf, err :=
(*cfg.TOClient).GetDeliveryServiceURISigningKeys(dsName)
+ err := torequtil.GetRetry(cl.NumRetries,
"urisigningkeys_"+string(dsName), &keys, func(obj interface{}) error {
+ toKeys, reqInf, err :=
cl.C.GetDeliveryServiceURISigningKeys(dsName)
if err != nil {
return errors.New("getting url sig keys from Traffic
Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -325,10 +371,10 @@ func GetURISigningKeys(cfg config.TCCfg, dsName string)
([]byte, error) {
return keys, nil
}
-func GetParametersByName(cfg config.TCCfg, paramName string) ([]tc.Parameter,
error) {
+func (cl *TOClient) GetParametersByName(paramName string) ([]tc.Parameter,
error) {
params := []tc.Parameter{}
- err := GetRetry(cfg, "parameters_name_"+paramName, ¶ms, func(obj
interface{}) error {
- toParams, reqInf, err :=
(*cfg.TOClient).GetParameterByName(paramName)
+ err := torequtil.GetRetry(cl.NumRetries, "parameters_name_"+paramName,
¶ms, func(obj interface{}) error {
+ toParams, reqInf, err := cl.C.GetParameterByName(paramName)
if err != nil {
return errors.New("getting parameters name '" +
paramName + "' from Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " +
err.Error())
}
@@ -342,10 +388,10 @@ func GetParametersByName(cfg config.TCCfg, paramName
string) ([]tc.Parameter, er
return params, nil
}
-func GetDeliveryServiceRegexes(cfg config.TCCfg) ([]tc.DeliveryServiceRegexes,
error) {
+func (cl *TOClient) GetDeliveryServiceRegexes() ([]tc.DeliveryServiceRegexes,
error) {
regexes := []tc.DeliveryServiceRegexes{}
- err := GetRetry(cfg, "ds_regexes", ®exes, func(obj interface{})
error {
- toRegexes, reqInf, err :=
(*cfg.TOClient).GetDeliveryServiceRegexes()
+ err := torequtil.GetRetry(cl.NumRetries, "ds_regexes", ®exes,
func(obj interface{}) error {
+ toRegexes, reqInf, err := cl.C.GetDeliveryServiceRegexes()
if err != nil {
return errors.New("getting ds regexes from Traffic Ops
'" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -359,10 +405,10 @@ func GetDeliveryServiceRegexes(cfg config.TCCfg)
([]tc.DeliveryServiceRegexes, e
return regexes, nil
}
-func GetJobs(cfg config.TCCfg) ([]tc.Job, error) {
+func (cl *TOClient) GetJobs() ([]tc.Job, error) {
jobs := []tc.Job{}
- err := GetRetry(cfg, "jobs", &jobs, func(obj interface{}) error {
- toJobs, reqInf, err := (*cfg.TOClient).GetJobs(nil, nil)
+ err := torequtil.GetRetry(cl.NumRetries, "jobs", &jobs, func(obj
interface{}) error {
+ toJobs, reqInf, err := cl.C.GetJobs(nil, nil)
if err != nil {
return errors.New("getting jobs from Traffic Ops '" +
MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -376,7 +422,7 @@ func GetJobs(cfg config.TCCfg) ([]tc.Job, error) {
return jobs, nil
}
-func GetServerCapabilitiesByID(cfg config.TCCfg, serverIDs []int)
(map[int]map[atscfg.ServerCapability]struct{}, error) {
+func (cl *TOClient) GetServerCapabilitiesByID(serverIDs []int)
(map[int]map[atscfg.ServerCapability]struct{}, error) {
serverIDsStr := ""
if len(serverIDs) > 0 {
sortIDsInHash := true
@@ -384,9 +430,9 @@ func GetServerCapabilitiesByID(cfg config.TCCfg, serverIDs
[]int) (map[int]map[a
}
serverCaps := map[int]map[atscfg.ServerCapability]struct{}{}
- err := GetRetry(cfg, "server_capabilities_s_"+serverIDsStr,
&serverCaps, func(obj interface{}) error {
+ err := torequtil.GetRetry(cl.NumRetries,
"server_capabilities_s_"+serverIDsStr, &serverCaps, func(obj interface{}) error
{
// TODO add list of IDs to API+Client
- toServerCaps, reqInf, err :=
(*cfg.TOClient).GetServerServerCapabilities(nil, nil, nil)
+ toServerCaps, reqInf, err :=
cl.C.GetServerServerCapabilities(nil, nil, nil)
if err != nil {
return errors.New("getting server caps from Traffic Ops
'" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -412,7 +458,7 @@ func GetServerCapabilitiesByID(cfg config.TCCfg, serverIDs
[]int) (map[int]map[a
return serverCaps, nil
}
-func GetDeliveryServiceRequiredCapabilitiesByID(cfg config.TCCfg, dsIDs []int)
(map[int]map[atscfg.ServerCapability]struct{}, error) {
+func (cl *TOClient) GetDeliveryServiceRequiredCapabilitiesByID(dsIDs []int)
(map[int]map[atscfg.ServerCapability]struct{}, error) {
dsIDsStr := ""
if len(dsIDs) > 0 {
sortIDsInHash := true
@@ -420,9 +466,9 @@ func GetDeliveryServiceRequiredCapabilitiesByID(cfg
config.TCCfg, dsIDs []int) (
}
dsCaps := map[int]map[atscfg.ServerCapability]struct{}{}
- err := GetRetry(cfg, "ds_capabilities_d_"+dsIDsStr, &dsCaps, func(obj
interface{}) error {
+ err := torequtil.GetRetry(cl.NumRetries, "ds_capabilities_d_"+dsIDsStr,
&dsCaps, func(obj interface{}) error {
// TODO add list of IDs to API+Client
- toDSCaps, reqInf, err :=
(*cfg.TOClient).GetDeliveryServicesRequiredCapabilities(nil, nil, nil)
+ toDSCaps, reqInf, err :=
cl.C.GetDeliveryServicesRequiredCapabilities(nil, nil, nil)
if err != nil {
return errors.New("getting ds caps from Traffic Ops '"
+ MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -448,10 +494,10 @@ func GetDeliveryServiceRequiredCapabilitiesByID(cfg
config.TCCfg, dsIDs []int) (
return dsCaps, nil
}
-func GetCDNSSLKeys(cfg config.TCCfg, cdnName tc.CDNName) ([]tc.CDNSSLKeys,
error) {
+func (cl *TOClient) GetCDNSSLKeys(cdnName tc.CDNName) ([]tc.CDNSSLKeys, error)
{
keys := []tc.CDNSSLKeys{}
- err := GetRetry(cfg, "cdn_sslkeys_"+string(cdnName), &keys, func(obj
interface{}) error {
- toKeys, reqInf, err :=
(*cfg.TOClient).GetCDNSSLKeys(string(cdnName))
+ err := torequtil.GetRetry(cl.NumRetries,
"cdn_sslkeys_"+string(cdnName), &keys, func(obj interface{}) error {
+ toKeys, reqInf, err := cl.C.GetCDNSSLKeys(string(cdnName))
if err != nil {
return errors.New("getting cdn ssl keys from Traffic
Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -465,10 +511,10 @@ func GetCDNSSLKeys(cfg config.TCCfg, cdnName tc.CDNName)
([]tc.CDNSSLKeys, error
return keys, nil
}
-func GetStatuses(cfg config.TCCfg) ([]tc.Status, error) {
+func (cl *TOClient) GetStatuses() ([]tc.Status, error) {
statuses := []tc.Status{}
- err := GetRetry(cfg, "statuses", &statuses, func(obj interface{}) error
{
- toStatus, reqInf, err := (*cfg.TOClient).GetStatuses()
+ err := torequtil.GetRetry(cl.NumRetries, "statuses", &statuses,
func(obj interface{}) error {
+ toStatus, reqInf, err := cl.C.GetStatuses()
if err != nil {
return errors.New("getting server update status from
Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -482,10 +528,10 @@ func GetStatuses(cfg config.TCCfg) ([]tc.Status, error) {
return statuses, nil
}
-func GetServerUpdateStatus(cfg config.TCCfg) (tc.ServerUpdateStatus, error) {
+func (cl *TOClient) GetServerUpdateStatus(cacheHostName tc.CacheName)
(tc.ServerUpdateStatus, error) {
status := tc.ServerUpdateStatus{}
- err := GetRetry(cfg, "server_update_status_"+string(cfg.CacheHostName),
&status, func(obj interface{}) error {
- toStatus, reqInf, err :=
(*cfg.TOClient).GetServerUpdateStatus(string(cfg.CacheHostName))
+ err := torequtil.GetRetry(cl.NumRetries,
"server_update_status_"+string(cacheHostName), &status, func(obj interface{})
error {
+ toStatus, reqInf, err :=
cl.C.GetServerUpdateStatus(string(cacheHostName))
if err != nil {
return errors.New("getting server update status from
Traffic Ops '" + MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
}
@@ -498,31 +544,3 @@ func GetServerUpdateStatus(cfg config.TCCfg)
(tc.ServerUpdateStatus, error) {
}
return status, nil
}
-
-// GetRetry attempts to get the given object from tempDir/cacheFileName,
retrying with exponential backoff up to cfg.NumRetries.
-// The cacheFileName is not used in actual fetching or logic, but only for
logging. It can be any printable string, but should be unique and reflect the
object being fetched.
-func GetRetry(cfg config.TCCfg, cacheFileName string, obj interface{}, getter
func(obj interface{}) error) error {
- start := time.Now()
- currentRetry := 0
- for {
- err := getter(obj)
- if err == nil {
- break
- }
- if strings.Contains(strings.ToLower(err.Error()), "not found") {
- // if the server returned a 404, retrying won't help
- return errors.New("getting uncached: " + err.Error())
- }
- if currentRetry == cfg.NumRetries {
- return errors.New("getting uncached: " + err.Error())
- }
-
- sleepSeconds := config.RetryBackoffSeconds(currentRetry)
- log.Warnf("getting '%v', sleeping for %v seconds: %v\n",
cacheFileName, sleepSeconds, err)
- currentRetry++
- time.Sleep(time.Second * time.Duration(sleepSeconds)) // TODO
make backoff configurable?
- }
-
- log.Infof("GetRetry %v retries %v took %v\n", cacheFileName,
currentRetry, time.Since(start).Round(time.Millisecond))
- return nil
-}
diff --git a/traffic_ops/ort/atstccfg/toreq/trafficops.go
b/traffic_ops/ort/atstccfg/toreq/trafficops.go
deleted file mode 100644
index 983a901..0000000
--- a/traffic_ops/ort/atstccfg/toreq/trafficops.go
+++ /dev/null
@@ -1,210 +0,0 @@
-package toreq
-
-/*
- * 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 (
- "bytes"
- "crypto/sha512"
- "encoding/base64"
- "errors"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "net/http/httptrace"
- "strconv"
- "time"
-
- "github.com/apache/trafficcontrol/lib/go-log"
- toclient "github.com/apache/trafficcontrol/traffic_ops/client"
- "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/config"
-)
-
-// GetTCCfg takes the config.Cfg and logs into Traffic Ops, returning the
TCCfg which contains the logged-in client.
-func GetTCCfg(cfg config.Cfg) (config.TCCfg, error) {
- log.Infoln("URL: '" + cfg.TOURL.String() + "' User: '" + cfg.TOUser +
"' Pass len: '" + strconv.Itoa(len(cfg.TOPass)) + "'")
-
- toFQDN := cfg.TOURL.Scheme + "://" + cfg.TOURL.Host
- log.Infoln("TO FQDN: '" + toFQDN + "'")
- log.Infoln("TO URL: '" + cfg.TOURL.String() + "'")
-
- toClient, toIP, err := toclient.LoginWithAgent(toFQDN, cfg.TOUser,
cfg.TOPass, cfg.TOInsecure, config.UserAgent, false, cfg.TOTimeout)
- if err != nil {
- return config.TCCfg{}, errors.New("Logging in to Traffic Ops '"
+ MaybeIPStr(toIP) + "': " + err.Error())
- }
-
- return config.TCCfg{Cfg: cfg, TOClient: &toClient}, nil
-}
-
-// TrafficOpsRequest makes a request to Traffic Ops for the given method, url,
and body.
-// If it gets an Unauthorized or Forbidden, it tries to log in again and makes
the request again.
-func TrafficOpsRequest(cfg config.TCCfg, method string, url string, body
[]byte) (string, int, error) {
- return trafficOpsRequestWithRetry(cfg, method, url, body,
cfg.NumRetries)
-}
-
-func trafficOpsRequestWithRetry(
- cfg config.TCCfg,
- method string,
- url string,
- body []byte,
- retryNum int,
-) (string, int, error) {
- currentRetry := 0
- for {
- body, code, err := trafficOpsRequestWithLogin(cfg, method, url,
body)
- if err == nil || currentRetry == retryNum {
- return body, code, err
- }
-
- sleepSeconds := config.RetryBackoffSeconds(currentRetry)
- log.Errorf("getting '%v' '%v', sleeping for %v seconds: %v\n",
method, url, sleepSeconds, err)
- currentRetry++
- time.Sleep(time.Second * time.Duration(sleepSeconds))
- }
-}
-
-func trafficOpsRequestWithLogin(
- cfg config.TCCfg,
- method string,
- url string,
- body []byte,
-) (string, int, error) {
- resp, toIP, err := rawTrafficOpsRequest(*cfg.TOClient, method, url,
body)
- if err != nil {
- toIPStr := ""
- if toIP != nil {
- toIPStr = toIP.String()
- }
- return "", 1, errors.New("requesting from Traffic Ops '" +
toIPStr + "': " + err.Error())
- }
-
- if resp.StatusCode == http.StatusUnauthorized || resp.StatusCode ==
http.StatusForbidden {
- resp.Body.Close()
-
- log.Infoln("TrafficOpsRequest got unauthorized/forbidden,
logging in again")
- log.Infof("TrafficOpsRequest url '%v' user '%v' pass '%v'\n",
(*cfg.TOClient).URL, (*cfg.TOClient).UserName, (*cfg.TOClient).Password)
-
- useCache := false
- newTOClient, toIP, err :=
toclient.LoginWithAgent((*cfg.TOClient).URL, (*cfg.TOClient).UserName,
(*cfg.TOClient).Password, cfg.TOInsecure, config.UserAgent, useCache,
cfg.TOTimeout)
- if err != nil {
- toIPStr := ""
- if toIP != nil {
- toIPStr = toIP.String()
- }
- return "", 1, errors.New("logging in to Traffic Ops IP
'" + toIPStr + "': " + err.Error())
- }
- *cfg.TOClient = newTOClient
-
- resp, toIP, err = rawTrafficOpsRequest(*cfg.TOClient, method,
url, body)
- if err != nil {
- toIPStr := ""
- if toIP != nil {
- toIPStr = toIP.String()
- }
- return "", 1, errors.New("requesting from Traffic Ops
'" + toIPStr + "': " + err.Error())
- }
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- bts, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- bts = []byte("(read failure)") // if it's a non-200 and
the body read fails, don't error, just note the read fail in the error
- }
- return "", resp.StatusCode, errors.New("Traffic Ops returned
non-200 code '" + strconv.Itoa(resp.StatusCode) + "' body '" + string(bts) +
"'")
- }
-
- bts, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- toIPStr := ""
- if toIP != nil {
- toIPStr = toIP.String()
- }
- return "", resp.StatusCode, errors.New("reading body from
Traffic Ops '" + toIPStr + "': " + err.Error())
- }
-
- if err := IntegrityCheck(resp.Header, bts, url); err != nil {
- return "", resp.StatusCode, errors.New("integrity check failed
for url '" + url + "': " + err.Error())
- }
-
- return string(bts), http.StatusOK, nil
-}
-
-func IntegrityCheck(hdr http.Header, body []byte, url string) error {
- if hdrSHA := hdr.Get("Whole-Content-SHA512"); hdrSHA != "" {
- realSHA := sha512.Sum512(body)
- realSHAStr := base64.StdEncoding.EncodeToString(realSHA[:])
- if realSHAStr != hdrSHA {
- return errors.New("Body does not match header
Whole-Content-SHA512")
- }
- log.Infoln("Integrity check for url '" + url + "' passed (sha
match)")
- return nil
- }
- if hdrLenStr := hdr.Get("Content-Length"); hdrLenStr != "" {
- hdrLen, err := strconv.Atoi(hdrLenStr)
- if err != nil {
- return errors.New("No Whole-Content-SHA512, and
Content-Length '" + hdrLenStr + "' is not an integer")
- }
- if hdrLen != len(body) {
- return errors.New("No Whole-Content-SHA512, and
Content-Length '" + hdrLenStr + "' does not match body length")
- }
- log.Infoln("Integrity check for url '" + url + "' passed
(length match)\n")
- return nil
- }
- return errors.New("No Whole-Content-SHA512, and no Content-Length,
cannot verify content")
-}
-
-// rawTrafficOpsRequest makes a request to Traffic Ops for the given method,
url, and body.
-// If it gets an Unauthorized or Forbidden, it tries to log in again and makes
the request again.
-func rawTrafficOpsRequest(toClient *toclient.Session, method string, url
string, body []byte) (*http.Response, net.Addr, error) {
- bodyReader := io.Reader(nil)
- if len(body) > 0 {
- bodyReader = bytes.NewBuffer(body)
- }
-
- remoteAddr := net.Addr(nil)
- req, err := http.NewRequest(method, url, bodyReader)
- if err != nil {
- return nil, remoteAddr, err
- }
-
- req = req.WithContext(httptrace.WithClientTrace(req.Context(),
&httptrace.ClientTrace{
- GotConn: func(connInfo httptrace.GotConnInfo) {
- remoteAddr = connInfo.Conn.RemoteAddr()
- },
- }))
-
- req.Header.Set("User-Agent", toClient.UserAgentStr)
-
- resp, err := toClient.Client.Do(req)
- if err != nil {
- return nil, remoteAddr, err
- }
-
- return resp, remoteAddr, nil
-}
-
-// MaybeIPStr returns the Traffic Ops IP string if it isn't nil, or the empty
string if it is.
-func MaybeIPStr(addr net.Addr) string {
- if addr != nil {
- return addr.String()
- }
- return ""
-}
diff --git a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/LICENSE
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/LICENSE
similarity index 100%
rename from traffic_ops/ort/vendor/github.com/apache/trafficcontrol/LICENSE
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/LICENSE
diff --git a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/VERSION
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/VERSION
similarity index 100%
rename from traffic_ops/ort/vendor/github.com/apache/trafficcontrol/VERSION
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/VERSION
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/changeset.txt
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/changeset.txt
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/changeset.txt
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/changeset.txt
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/README.md
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/README.md
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/README.md
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/README.md
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/about.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/about.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/about.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/about.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/asn.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/asn.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/asn.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/asn.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/atsconfig.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/atsconfig.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/atsconfig.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/atsconfig.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup_parameters.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup_parameters.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup_parameters.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cachegroup_parameters.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn_domains.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn_domains.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn_domains.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdn_domains.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdnfederations.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdnfederations.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdnfederations.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/cdnfederations.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/coordinate.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/coordinate.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/coordinate.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/coordinate.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/crconfig.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/crconfig.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/crconfig.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/crconfig.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_endpoints.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_endpoints.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_endpoints.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_endpoints.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_request_comments.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_request_comments.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_request_comments.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_request_comments.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_requests.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_requests.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_requests.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservice_requests.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservices_required_capabilities.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservices_required_capabilities.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservices_required_capabilities.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryservices_required_capabilities.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryserviceserver.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryserviceserver.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryserviceserver.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/deliveryserviceserver.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/division.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/division.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/division.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/division.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/dsuser.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/dsuser.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/dsuser.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/dsuser.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/endpoints.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/endpoints.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/endpoints.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/endpoints.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation_resolver.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation_resolver.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation_resolver.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/federation_resolver.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/hardware.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/hardware.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/hardware.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/hardware.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/iso.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/iso.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/iso.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/iso.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/job.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/job.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/job.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/job.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/log.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/log.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/log.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/log.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/origin.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/origin.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/origin.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/origin.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/parameter.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/parameter.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/parameter.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/parameter.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/phys_location.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/phys_location.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/phys_location.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/phys_location.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/ping.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/ping.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/ping.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/ping.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile_parameter.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile_parameter.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile_parameter.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/profile_parameter.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/region.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/region.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/region.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/region.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/role.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/role.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/role.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/role.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_server_capabilities.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_server_capabilities.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_server_capabilities.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_server_capabilities.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_update_status.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_update_status.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_update_status.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/server_update_status.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercapability.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercapability.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercapability.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercapability.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercheck.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercheck.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercheck.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/servercheck.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/serversstatus.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/serversstatus.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/serversstatus.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/serversstatus.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/session.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/session.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/session.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/session.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/staticdnsentry.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/staticdnsentry.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/staticdnsentry.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/staticdnsentry.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/stats_summary.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/stats_summary.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/stats_summary.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/stats_summary.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/status.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/status.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/status.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/status.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steering.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steering.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steering.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steering.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steeringtarget.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steeringtarget.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steeringtarget.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/steeringtarget.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant_endpoints.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant_endpoints.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant_endpoints.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/tenant_endpoints.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/toextension.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/toextension.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/toextension.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/toextension.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_monitor.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_monitor.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_monitor.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_monitor.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_stats.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_stats.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_stats.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/traffic_stats.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/type.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/type.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/type.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/type.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/update.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/update.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/update.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/update.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/user.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/user.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/user.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/user.go
diff --git
a/traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/util.go
b/traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/util.go
similarity index 100%
rename from
traffic_ops/ort/vendor/github.com/apache/trafficcontrol/traffic_ops/client/util.go
rename to
traffic_ops/ort/atstccfg/toreq/vendor/github.com/apache/trafficcontrol/traffic_ops/client/util.go
diff --git a/traffic_ops/ort/atstccfg/toreqnew/toreqnew.go
b/traffic_ops/ort/atstccfg/toreqnew/toreqnew.go
new file mode 100644
index 0000000..e7141f3
--- /dev/null
+++ b/traffic_ops/ort/atstccfg/toreqnew/toreqnew.go
@@ -0,0 +1,97 @@
+// toreqnew implements a Traffic Ops client for features in the latest version.
+//
+// This should only be used if an endpoint or field needed for config gen is
in the latest.
+//
+// Users should always check the returned bool, and if it's false, call the
vendored toreq client and set the proper defaults for the new feature(s).
+//
+// All TOClient functions should check for 404 or 503 and return a bool false
if so.
+//
+package toreqnew
+
+/*
+ * 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"
+ "net/http/cookiejar"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+
+ "golang.org/x/net/publicsuffix"
+
+ "github.com/apache/trafficcontrol/lib/go-log"
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ toclient "github.com/apache/trafficcontrol/traffic_ops/client"
+ "github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg/torequtil"
+)
+
+type TOClient struct {
+ C *toclient.Session
+ NumRetries int
+}
+
+// New returns a TOClient with the given credentials.
+// Note it does not actually log in or try to make a request. Rather, it
assumes the cookies are valid for a session. No external communication is made.
+func New(cookies string, url *url.URL, user string, pass string, insecure
bool, timeout time.Duration, userAgent string) (*TOClient, error) {
+ log.Infoln("URL: '" + url.String() + "' User: '" + user + "' Pass len:
'" + strconv.Itoa(len(pass)) + "'")
+
+ useCache := false
+ toClient := toclient.NewNoAuthSession(url.String(), insecure,
userAgent, useCache, timeout)
+ toClient.UserName = user
+ toClient.Password = pass
+
+ jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList:
publicsuffix.List})
+ if err != nil {
+ return nil, errors.New("making cookie jar: " + err.Error())
+ }
+ toClient.Client.Jar = jar
+ toClient.Client.Jar.SetCookies(url, torequtil.StringToCookies(cookies))
+
+ return &TOClient{C: toClient}, nil
+}
+
+// GetCDNDeliveryServices returns the deliveryservices, whether this client's
version is unsupported by the server, and any error.
+// Note if the server returns a 404 or 503, this returns false and a nil error.
+// Users should check the "not supported" bool, and use the vendored TOClient
if it's set, and set proper defaults for the new feature(s).
+func (cl *TOClient) GetCDNDeliveryServices(cdnID int)
([]tc.DeliveryServiceNullable, bool, error) {
+ deliveryServices := []tc.DeliveryServiceNullable{}
+ unsupported := false
+ err := torequtil.GetRetry(cl.NumRetries,
"cdn_"+strconv.Itoa(cdnID)+"_deliveryservices", &deliveryServices, func(obj
interface{}) error {
+ toDSes, reqInf, err := cl.C.GetDeliveryServicesByCDNID(cdnID)
+ if err != nil {
+ if errStr := strings.ToLower(err.Error());
strings.Contains(errStr, "not found") || strings.Contains(errStr, "not impl") {
+ unsupported = true
+ return nil
+ }
+ return errors.New("getting delivery services from
Traffic Ops '" + torequtil.MaybeIPStr(reqInf.RemoteAddr) + "': " + err.Error())
+ }
+ dses := obj.(*[]tc.DeliveryServiceNullable)
+ *dses = toDSes
+ return nil
+ })
+ if unsupported {
+ return nil, true, nil
+ }
+ if err != nil {
+ return nil, false, errors.New("getting delivery services: " +
err.Error())
+ }
+ return deliveryServices, false, nil
+}
diff --git a/traffic_ops/ort/atstccfg/torequtil/torequtil.go
b/traffic_ops/ort/atstccfg/torequtil/torequtil.go
new file mode 100644
index 0000000..726858f
--- /dev/null
+++ b/traffic_ops/ort/atstccfg/torequtil/torequtil.go
@@ -0,0 +1,90 @@
+// torequtil has utility functions used by toreq and toreqnew
+// which don't require the Traffic Ops client, and thus can be shared.
+package torequtil
+
+/*
+ * 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"
+ "math"
+ "net"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-log"
+)
+
+// GetRetry attempts to get the given object, retrying with exponential
backoff up to cfg.NumRetries.
+// The objName is not used in actual fetching or logic, but only for logging.
It can be any printable string, but should be unique and reflect the object
being fetched.
+func GetRetry(numRetries int, objName string, obj interface{}, getter func(obj
interface{}) error) error {
+ start := time.Now()
+ currentRetry := 0
+ for {
+ err := getter(obj)
+ if err == nil {
+ break
+ }
+ if strings.Contains(strings.ToLower(err.Error()), "not found") {
+ // if the server returned a 404, retrying won't help
+ return errors.New("getting uncached: " + err.Error())
+ }
+ if currentRetry == numRetries {
+ return errors.New("getting uncached: " + err.Error())
+ }
+
+ sleepSeconds := RetryBackoffSeconds(currentRetry)
+ log.Warnf("getting '%v', sleeping for %v seconds: %v\n",
objName, sleepSeconds, err)
+ currentRetry++
+ time.Sleep(time.Second * time.Duration(sleepSeconds)) // TODO
make backoff configurable?
+ }
+
+ log.Infof("GetRetry %v retries %v took %v\n", objName, currentRetry,
time.Since(start).Round(time.Millisecond))
+ return nil
+}
+
+func RetryBackoffSeconds(currentRetry int) int {
+ // TODO make configurable?
+ return int(math.Pow(2.0, float64(currentRetry)))
+}
+
+// MaybeIPStr returns the addr string if it isn't nil, or the empty string if
it is.
+// This is intended for logging, to allow logging with one line, whether addr
is nil or not.
+func MaybeIPStr(addr net.Addr) string {
+ if addr != nil {
+ return addr.String()
+ }
+ return ""
+}
+
+func StringToCookies(cookiesStr string) []*http.Cookie {
+ hdr := http.Header{}
+ hdr.Add("Cookie", cookiesStr)
+ req := http.Request{Header: hdr}
+ return req.Cookies()
+}
+
+func CookiesToString(cookies []*http.Cookie) string {
+ strs := []string{}
+ for _, cookie := range cookies {
+ strs = append(strs, cookie.String())
+ }
+ return strings.Join(strs, "; ")
+}
diff --git a/traffic_ops/ort/atstccfg/torequtil/torequtil_test.go
b/traffic_ops/ort/atstccfg/torequtil/torequtil_test.go
new file mode 100644
index 0000000..533a0db
--- /dev/null
+++ b/traffic_ops/ort/atstccfg/torequtil/torequtil_test.go
@@ -0,0 +1,70 @@
+package torequtil
+
+/*
+ * 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"
+ "net"
+ "strings"
+ "testing"
+)
+
+func TestGetRetry(t *testing.T) {
+ getterCalled := 0
+ getter := func(obj interface{}) error {
+ getterCalled++
+ return errors.New("something")
+ }
+
+ numRetries := 2
+ err := GetRetry(numRetries, "foo", nil, getter)
+ if err == nil {
+ t.Fatal("GetRetry expected error from f, actual nil")
+ }
+ if errStr := err.Error(); !strings.Contains(errStr, "something") {
+ t.Errorf("GetRetry expected error from getter 'something',
actual '" + errStr + "'")
+ }
+ if getterCalled != numRetries+1 { // +1 because the first call isn't a
retry.
+ t.Errorf("GetRetry expected to call getter numRetries %v +1
times, actual %v\n", numRetries, getterCalled)
+ }
+}
+
+func TestRetryBackoffSeconds(t *testing.T) {
+ // Just test that it's greater. We don't want a brittle test that tests
exactly how we know the function increases.
+ currentRetry := 0
+ newRetry := RetryBackoffSeconds(currentRetry)
+ if newRetry <= currentRetry {
+ t.Errorf("RetryBackoffSeconds expected greater than current
retry %v actual %v", currentRetry, newRetry)
+ }
+ newerRetry := RetryBackoffSeconds(newRetry)
+ if newerRetry <= newRetry {
+ t.Errorf("RetryBackoffSeconds expected greater than new retry
%v actual %v", currentRetry, newRetry)
+ }
+}
+
+func TestMaybeIPStr(t *testing.T) {
+ if is := MaybeIPStr(nil); is != "" {
+ t.Errorf("MaybeIPStr(nil) expected '', actual '%v'", is)
+ }
+ addr := &net.IPAddr{IP: net.ParseIP("192.0.2.1")}
+ if is := MaybeIPStr(addr); is != "192.0.2.1" {
+ t.Errorf("MaybeIPStr(nil) expected '192.0.2.1', actual '%v'",
is)
+ }
+}
diff --git a/traffic_ops/ort/atstccfg/update-to-client/update-to-client.go
b/traffic_ops/ort/atstccfg/update-to-client/update-to-client.go
new file mode 100644
index 0000000..99855df
--- /dev/null
+++ b/traffic_ops/ort/atstccfg/update-to-client/update-to-client.go
@@ -0,0 +1,290 @@
+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"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+func main() {
+ if len(os.Args) < 3 {
+ fmt.Fprintf(os.Stdout, usageStr())
+ os.Exit(0)
+ }
+ dir := os.Args[1]
+ branch := os.Args[2]
+
+ workingDir, err := os.Getwd()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error getting working directory:
"+err.Error()+"\n")
+ os.Exit(1)
+ }
+
+ dir = filepath.Join(workingDir, dir) // make the given directory
absolute
+
+ if err := updateVendoredTOClient(dir, branch); err != nil {
+ fmt.Fprintf(os.Stderr, "Error updating vendored client:
"+err.Error()+"\n")
+ os.Exit(1)
+ }
+ if err := updateNewClientUsage(dir); err != nil {
+ fmt.Fprintf(os.Stderr, "Error updating new client usage:
"+err.Error()+"\n")
+ os.Exit(1)
+ }
+ os.Exit(0)
+}
+
+func usageStr() string {
+ return `usage: go run update-to-client.go
/path/to/traffic_ops/ort/atstccfg branch-to-vendor
+
+Example: go run update-to-client/update-to-client.go . 5.0.x
+
+This script updates traffic_ops/ort/atstccfg after a Traffic Ops release is
made.
+
+Be aware! It can and will modify all .go files in the given directory! Back up
any uncommitted changes!
+
+Also be aware! This is very specific to the current code. If symbols or
patterns are changed around how the master vs vendored client are used, this
script will have to be updated.
+
+Expecations:
+- atstccfg is at github.com/apache/trafficcontrol/traffic_ops/ort/atstccfg
+- The master TO client is at
github.com/apache/trafficcontrol/traffic_ops/client
+- The previous major version client is vendored at atstccfg/toreq/vendor
+- The master client wrapper for atstccfg is at atstccfg/toreqnew
+- The clients are stored in config.TCCfg.TOClient and config.TCCfg.TOClientNew
+- Every func in toreqnew.TOClient has a corresponding func with the same name
in toreq.TOClient
+- Every func in toreqnew.TOClient returns 3 variables: the object, boolean
whether the request was unsupported, and an error.
+- Every func in toreq.TOClient returns 2 variables: the object, and an error.
+- Every usage of config.TOClientNew is immediately followed by a check 'if err
== nil && unsupported', whose block calls the old client and sets defaults for
the unsupported new feature.
+- The script is running on a POSIX-like environment. Namely, cp and gofmt
exist.
+
+The arguments are the atstccfg directory, and the name of the branch to vendor
from.
+
+This script should always be called from
trafficcontrol/traffic_ops/ort/atstccfg.
+
+It copies the traffic_ops/client from that branch into toreq/vendor,
+and then updates all references to cfg.TOClientNew to cfg.TOClient.
+
+This must be done as soon as a release is made, before any new features are
added to ort/atstccfg.
+Thus, all existing toreqnew.TOClient function calls should exist in master.
+
+If any new features were added after a release, before you ran this script,
+you'll have to go back and fix compile errors for new client functions.
+
+Further, if the new features were fields on existing functions, being moved
+from toreqnew to toreq will make them still compile, but the fields will be
nil!
+
+It will also run gofmt on all go files in the directory (because it's much
easier to manipulate code guaranteed to be gofmt'd).
+
+Double check the results before you commit!
+`
+}
+
+func updateNewClientUsage(appDir string) error {
+ paths := []string{}
+ err := filepath.Walk(appDir,
+ func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if !strings.HasSuffix(path, `.go`) {
+ return nil // skip anything not a go file.
+ }
+ if strings.Contains(path, `/vendor/`) {
+ return nil // skip vendored code
+ }
+ if strings.HasPrefix(filepath.Base(path), `.`) {
+ return nil // skip .files (usually created by
editors)
+ }
+ if strings.Contains(path, `update-to-client.go`) {
+ return nil // skip this file
+ }
+
+ paths = append(paths, path)
+ return nil
+ })
+ if err != nil {
+ return errors.New("reading directory: " + err.Error() + "\n")
+ }
+
+ toClientNewRe := regexp.MustCompile(`(\s+)([^\s]+), (.+), (.+) :=
(.+).TOClientNew.(.+)$`)
+
+ for _, path := range paths {
+ // gofmt the file, because the parsing relies on things being
in that exact format.
+ if err := exec.Command(`gofmt`, `-w`, path).Run(); err != nil {
+ return errors.New("running gofmt on '" + path + ": " +
err.Error() + "\n")
+ }
+
+ bts, err := ioutil.ReadFile(path)
+ if err != nil {
+ return errors.New("reading file '" + path + "': " +
err.Error() + "\n")
+ }
+
+ lines := strings.Split(string(bts), "\n")
+ newLines := make([]string, 0, len(lines))
+
+ const stateStart = 0
+ const stateInFoundTOClientNew = 1
+ const stateInTOClientNewUnsupportedBlock = 2
+
+ state := stateStart
+ spacePrefix := ""
+ objVar := ""
+ unsupportedVar := ""
+ errVar := ""
+ for _, line := range lines {
+ switch state {
+ case stateStart:
+ if strings.Contains(line, `.TOClientNew.`) {
+ matches :=
toClientNewRe.FindStringSubmatch(line)
+ if len(matches) != 7 {
+ // TODO is this really an
error? Skip and continue?
+ return fmt.Errorf("parsing file
'"+path+"': line contains TOClientNew, but is unexpected format (only %v
matches): '"+line+"'\n", len(matches))
+ }
+ spacePrefix = matches[1]
+ objVar = matches[2]
+ unsupportedVar = matches[3]
+ errVar = matches[4]
+ cfg := matches[5]
+ funcStr := matches[6]
+ newLine := spacePrefix + objVar + `, `
+ errVar + ` := ` + cfg + `.TOClient.` + funcStr
+ newLines = append(newLines, newLine)
+ state = stateInFoundTOClientNew
+ continue
+ }
+ newLines = append(newLines, line)
+ case stateInFoundTOClientNew:
+ // if there's a newline between the call and
the unsupported check, skip it.
+ if strings.TrimSpace(line) == "" {
+ continue
+ }
+ if line == spacePrefix+`if `+errVar+` == nil &&
`+unsupportedVar+` {` ||
+ line == spacePrefix+`if
`+unsupportedVar+` && `+errVar+` == nil `+` {` ||
+ line == spacePrefix+`if
`+unsupportedVar+` {` ||
+ line == spacePrefix+`if
`+unsupportedVar+` {` {
+ state =
stateInTOClientNewUnsupportedBlock
+ continue // continue without adding
this line - we want to remove the check-and-fallback
+ }
+ return errors.New("parsing file '" + path + "':
line contains TOClientNew, but is unexpected format: not followed by a check
for the unsupported bool (or the parser failed to understand it)\n")
+ case stateInTOClientNewUnsupportedBlock:
+ // This is why we have to gofmt - if we didn't,
we couldn't be guarnateed the block closing would be prefixed by exactly this
many spaces. Then we'd have to parse the AST to find it. Ick.
+ if line == spacePrefix+`}` {
+ state = stateStart
+ }
+ // Whether or not we find the closing block,
don't add it to the lines to output.
+ // We want to remove the TOClientNew
check-and-fallback block from the output.
+ }
+ }
+ if state != stateStart {
+ return errors.New("parsing modified file '" + path +
"': appeared to be malformed (or maybe our parser is just broken, sorry)\n")
+ }
+
+ newFile := strings.Join(newLines, "\n")
+
+ if err := ioutil.WriteFile(path, []byte(newFile), 0644); err !=
nil {
+ return errors.New("writing modified file '" + path +
"': " + err.Error() + "\n")
+ }
+ }
+ return nil
+}
+
+func updateVendoredTOClient(appDir string, branch string) error {
+ vendorDir := filepath.Join(appDir, `toreq`, `vendor`)
+ vendorTCDir := filepath.Join(vendorDir, `github.com`, `apache`,
`trafficcontrol`)
+ vendorClientDir := filepath.Join(vendorTCDir, `traffic_ops`, `client`)
+
+ vendorFileInfo, err := os.Stat(vendorClientDir)
+ if err != nil {
+ return errors.New("getting vendor dir '" + vendorDir + "' info:
" + err.Error())
+ }
+ if !vendorFileInfo.IsDir() {
+ return errors.New("getting vendor dir '" + vendorDir + "' info:
not a directory")
+ }
+ if err := os.RemoveAll(vendorClientDir); err != nil {
+ return errors.New("removing vendor dir '" + vendorDir + "': " +
err.Error())
+ }
+ if err := os.Mkdir(vendorClientDir, 0755); err != nil {
+ return errors.New("creating vendor dir '" + vendorDir + "': " +
err.Error())
+ }
+
+ cmd := exec.Command(`git`, `show`, branch+`:../../client`)
+ cmd.Dir = appDir
+ clientFileListBts, err := cmd.Output()
+ if err != nil {
+ return errors.New("getting files from git: " + err.Error())
+ }
+ clientFileListStr := string(clientFileListBts)
+ clientFileList := strings.Split(clientFileListStr, "\n")
+ if len(clientFileList) < 2 {
+ return errors.New("getting files from git: got no files")
+ }
+ clientFileList = clientFileList[1:] // first line is a header, remove
it.
+ // fmt.Printf("DEBUG got client file list '''%+v'''\n",
clientFileListStr)
+
+ for _, clientFile := range clientFileList {
+ clientFile = strings.TrimSpace(clientFile)
+ if clientFile == "" {
+ continue
+ }
+ cmd := exec.Command(`git`, `show`,
branch+`:../../client`+`/`+clientFile)
+ cmd.Dir = appDir
+ fileBts, err := cmd.Output()
+ if err != nil {
+ return errors.New("getting client file '" + clientFile
+ "' from git: " + err.Error())
+ }
+ if err := ioutil.WriteFile(vendorClientDir+`/`+clientFile,
fileBts, 0644); err != nil {
+ return errors.New("Error writing vendored file '" +
clientFile + "': " + err.Error())
+ }
+ }
+
+ // update VERSION in vendored dir
+ cmd = exec.Command(`git`, `show`, branch+`:VERSION`)
+ cmd.Dir = appDir
+ versionBts, err := cmd.Output()
+ if err != nil {
+ return errors.New("getting VERSION file from git: " +
err.Error())
+ }
+
+ versionPath := filepath.Join(vendorTCDir, `VERSION`)
+ if err := ioutil.WriteFile(versionPath, versionBts, 0644); err != nil {
+ return errors.New("Error writing vendored VERSION file '" +
versionPath + "': " + err.Error())
+ }
+
+ cmd = exec.Command(`git`, `rev-parse`, branch)
+ cmd.Dir = appDir
+ changesetBts, err := cmd.Output()
+ if err != nil {
+ return errors.New("getting VERSION file from git: " +
err.Error())
+ }
+
+ changesetTxt := branch + "\n" + string(changesetBts)
+
+ changesetTxtPath := filepath.Join(vendorTCDir, `changeset.txt`)
+ if err := ioutil.WriteFile(changesetTxtPath, []byte(changesetTxt),
0644); err != nil {
+ return errors.New("Error writing vendored changeset.txt file '"
+ changesetTxtPath + "': " + err.Error())
+ }
+
+ return nil
+}