Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#6066](https://github.com/apache/trafficcontrol/issues/6066) - Fixed missing/incorrect indices on some tables
- [#6169](https://github.com/apache/trafficcontrol/issues/6169) - Fixed t3c-update not updating server status when a fallback to a previous Traffic Ops API version occurred
- [#5576](https://github.com/apache/trafficcontrol/issues/5576) - Inconsistent Profile Name restrictions
- [#6327](https://github.com/apache/trafficcontrol/issues/6327) - Fixed cache config to invalidate its cache if the Server's Profile or CDN changes
- [#6174](https://github.com/apache/trafficcontrol/issues/6174) - Fixed t3c-apply with no hostname failing if the OS hostname returns a full FQDN
- Fixed Federations IMS so TR federations watcher will get updates.
- [#5129](https://github.com/apache/trafficcontrol/issues/5129) - Updated TM so that it returns a 404 if the endpoint is not supported.
Expand Down
29 changes: 21 additions & 8 deletions cache-config/t3cutil/getdatacfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ type ConfigData struct {
}

type ConfigDataMetaData struct {
CacheHostName string `json:"cache_host_name"`
Servers ReqMetaData `json:"servers"`
CacheGroups ReqMetaData `json:"cache_groups"`
GlobalParams ReqMetaData `json:"global_parameters"`
Expand Down Expand Up @@ -176,6 +177,7 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st

toIPs := &sync.Map{} // each Traffic Ops request could get a different IP, so track them all
toData := &ConfigData{}
toData.MetaData.CacheHostName = cacheHostName

{
reqHdr := (http.Header)(nil)
Expand Down Expand Up @@ -220,6 +222,16 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st
log.Infoln("Traffic Ops proxy is disabled, not checking or using GLOBAL Parameter '" + TrafficOpsProxyParameterName)
}

oldServer := &atscfg.Server{}
if oldCfg != nil {
for _, toServer := range oldCfg.Servers {
if toServer.HostName != nil && *toServer.HostName == oldCfg.MetaData.CacheHostName {
oldServer = &toServer
break
}
}
}

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
Expand Down Expand Up @@ -267,8 +279,9 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st
defer func(start time.Time) { log.Infof("sslF took %v\n", time.Since(start)) }(time.Now())

{

reqHdr := (http.Header)(nil)
if oldCfg != nil {
if oldCfg != nil && oldServer.CDNName != nil && *oldServer.CDNName == *server.CDNName {
reqHdr = MakeReqHdr(oldCfg.MetaData.SSLKeys)
}
keys, reqInf, err := toClient.GetCDNSSLKeys(tc.CDNName(*server.CDNName), reqHdr)
Expand All @@ -293,7 +306,7 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st

{
reqHdr := (http.Header)(nil)
if oldCfg != nil {
if oldCfg != nil && oldServer.CDNName != nil && *oldServer.CDNName == *server.CDNName {
reqHdr = MakeReqHdr(oldCfg.MetaData.DeliveryServices)
}
dses, reqInf, err := toClient.GetCDNDeliveryServices(*server.CDNID, reqHdr)
Expand Down Expand Up @@ -329,7 +342,7 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st

{
reqHdr := (http.Header)(nil)
if oldCfg != nil {
if oldCfg != nil && oldServer.CDNName != nil && *oldServer.CDNName == *server.CDNName {
reqHdr = MakeReqHdr(oldCfg.MetaData.DeliveryServiceServers)
}
dss, reqInf, err := toClient.GetDeliveryServiceServers(nil, nil, *server.CDNName, reqHdr)
Expand Down Expand Up @@ -447,7 +460,7 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st
defer func(start time.Time) { log.Infof("serverParamsF took %v\n", time.Since(start)) }(time.Now())
{
reqHdr := (http.Header)(nil)
if oldCfg != nil {
if oldCfg != nil && oldServer.Profile != nil && *oldServer.Profile == *server.Profile {
reqHdr = MakeReqHdr(oldCfg.MetaData.ServerParams)
}
params, reqInf, err := toClient.GetServerProfileParameters(*server.Profile, reqHdr)
Expand All @@ -473,7 +486,7 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st
defer func(start time.Time) { log.Infof("cdnF took %v\n", time.Since(start)) }(time.Now())
{
reqHdr := (http.Header)(nil)
if oldCfg != nil {
if oldCfg != nil && oldServer.CDNName != nil && *oldServer.CDNName == *server.CDNName {
reqHdr = MakeReqHdr(oldCfg.MetaData.CDN)
}
cdn, reqInf, err := toClient.GetCDN(tc.CDNName(*server.CDNName), reqHdr)
Expand All @@ -496,8 +509,8 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st
defer func(start time.Time) { log.Infof("profileF took %v\n", time.Since(start)) }(time.Now())
{
reqHdr := (http.Header)(nil)
if oldCfg != nil {
reqHdr = MakeReqHdr(oldCfg.MetaData.GlobalParams)
if oldCfg != nil && oldServer.Profile != nil && *oldServer.Profile == *server.Profile {
reqHdr = MakeReqHdr(oldCfg.MetaData.Profile)
}
profile, reqInf, err := toClient.GetProfileByName(*server.Profile, reqHdr)
if err != nil {
Expand All @@ -519,7 +532,7 @@ func GetConfigData(toClient *toreq.TOClient, disableProxy bool, cacheHostName st
defer func(start time.Time) { log.Infof("jobsF took %v\n", time.Since(start)) }(time.Now())
{
reqHdr := (http.Header)(nil)
if oldCfg != nil {
if oldCfg != nil && oldServer.CDNName != nil && *oldServer.CDNName == *server.CDNName {
reqHdr = MakeReqHdr(oldCfg.MetaData.Jobs)
}
jobs, reqInf, err := toClient.GetJobs(reqHdr, *server.CDNName)
Expand Down
127 changes: 127 additions & 0 deletions cache-config/testing/ort-tests/t3c-ims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,20 @@ package orttest
*/

import (
"bytes"
"errors"
"io/ioutil"
"net/url"
"path/filepath"
"strings"
"testing"

"github.com/apache/trafficcontrol/cache-config/t3cutil"
"github.com/apache/trafficcontrol/cache-config/testing/ort-tests/tcdata"
testutil "github.com/apache/trafficcontrol/cache-config/testing/ort-tests/util"
"github.com/apache/trafficcontrol/lib/go-tc"
"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
toclient "github.com/apache/trafficcontrol/traffic_ops/v3-client"
)

func TestIMS(t *testing.T) {
Expand All @@ -33,6 +41,7 @@ func TestIMS(t *testing.T) {
tcdata.DeliveryServices}, func() {

doTestIMS(t)
doTestIMSChangedCDN(t)

})
t.Logf("------------- End of TestIMS ---------------")
Expand Down Expand Up @@ -67,6 +76,111 @@ func doTestIMS(t *testing.T) {
t.Logf("------------- End doTestIMS ---------------")
}

// doTestIMSChangedCDN tests that after caching, requests which use the CDN as a key don't use the invalid cache.
func doTestIMSChangedCDN(t *testing.T) {
t.Logf("------------- Start doTestIMSChangedCDN ---------------")
defer func() { t.Logf("------------- End doTestIMSChangedCDN ---------------") }()

cacheHostName := "atlanta-edge-03"

t.Logf("doTestIMSChangedCDN calling badass with cache")
if stdOut, exitCode := t3cApplyCache(cacheHostName, false); exitCode != 0 {
t.Fatalf("ERROR: t3c badass failed: code '%v' output '%v'\n", exitCode, stdOut)
}

if !testutil.FileExists(t3cutil.ApplyCachePath) {
t.Fatalf("expected: cache '%v' to exist after badass, actual: doesn't exist", t3cutil.ApplyCachePath)
}

if stdOut, exitCode := t3cApplyCache(cacheHostName, false); exitCode != 0 {
t.Fatalf("ERROR: t3c badass failed: code '%v' output '%v'\n", exitCode, stdOut)
} else if !strings.Contains(stdOut, "not modified, using old config") {
t.Errorf("ERROR: expected t3c second badass to have a successful IMS 304, actual: code '%v' output '%v'\n", exitCode, stdOut)
}

cdn1Domain := "test.cdn1.net"
cdn2Domain := "test.cdn2.net"
cdn2ProfileName := "ATS_EDGE_TIER_CACHE_CDN2"

{
// check that remap.config has the initial cdn1

remapName := filepath.Join(test_config_dir, "remap.config")
remapDotConfig, err := ioutil.ReadFile(remapName)
if err != nil {
t.Fatalf("reading %v: %v\n", remapName, err)
}

if !bytes.Contains(remapDotConfig, []byte(cdn1Domain)) {
t.Errorf("expected remap.config to contain cdn1 domain '%v', actual: '%v'\n", cdn1Domain, string(remapDotConfig))
}
}

{
// change the server's CDN

cdn2Name := "cdn2"
cdns, _, err := tcdata.TOSession.GetCDNByNameWithHdr(cdn2Name, nil)
if err != nil {
t.Fatalf("getting cdn: " + err.Error())
} else if len(cdns) != 1 {
t.Fatalf("getting cdn: expected 1 cdn actual num %v cdns %+v", len(cdns), cdns)
}

// have to change the profile at the same time, or TO will reject the change.
profiles, _, err := tcdata.TOSession.GetProfileByNameWithHdr(cdn2ProfileName, nil)
if err != nil {
t.Fatalf("getting profile: " + err.Error())
} else if len(cdns) != 1 {
t.Fatalf("getting profile: expected 1 cdn actual num %v objects %+v", len(profiles), profiles)
}

cdn2ID := cdns[0].ID
cdn2ProfileID := profiles[0].ID

sv, _, err := GetServer(tcdata.TOSession, cacheHostName)
if err != nil {
t.Fatalf("getting server: " + err.Error())
}

sv.CDNID = &cdn2ID
sv.CDNName = &cdn2Name
sv.ProfileID = &cdn2ProfileID
sv.Profile = &cdn2ProfileName

_, _, err = tcdata.TOSession.UpdateServerByIDWithHdr(*sv.ID, *sv, nil)
if err != nil {
t.Fatalf("updating server: " + err.Error())
}
}

// run t3c after changing the cdn

stdOut, exitCode := t3cApplyCache(cacheHostName, false)
if exitCode != 0 {
t.Fatalf("ERROR: t3c badass failed: code '%v' output '%v'\n", exitCode, stdOut)
}

{
// check that remap.config has the changed cdn2, and does not have the old cdn1

remapName := filepath.Join(test_config_dir, "remap.config")
remapDotConfig, err := ioutil.ReadFile(remapName)
if err != nil {
t.Fatalf("reading %v: %v\n", remapName, err)
}

if !bytes.Contains(remapDotConfig, []byte(cdn2Domain)) {
t.Errorf("expected after changing server to cdn2 for remap.config to contain cdn2 domain '%v', actual: '%v'\n", cdn2Domain, string(remapDotConfig))
}

if bytes.Contains(remapDotConfig, []byte(cdn1Domain)) {
t.Errorf("expected after changing server to cdn2 for remap.config to not contain cdn1 domain '%v', actual: '%v'\n", cdn1Domain, string(remapDotConfig))
}
}

}

func t3cApplyCache(host string, noCache bool) (string, int) {
args := []string{
"apply",
Expand All @@ -87,3 +201,16 @@ func t3cApplyCache(host string, noCache bool) (string, int) {
_, stdErr, exitCode := t3cutil.Do("t3c", args...) // should be no stdout, we told it to log to stderr
return string(stdErr), exitCode
}

func GetServer(toClient *toclient.Session, hostName string) (*tc.ServerV30, toclientlib.ReqInf, error) {
params := url.Values{}
params.Add("hostName", hostName)
resp, reqInf, err := toClient.GetServersWithHdr(&params, nil)
if err != nil {
return nil, reqInf, err
}
if len(resp.Response) == 0 {
return nil, reqInf, errors.New("not found")
}
return &resp.Response[0], reqInf, nil
}
Loading