in traffic_ops/traffic_ops_golang/crconfig/deliveryservice.go [46:454]
func makeDSes(cdn string, domain string, ttlOverride int, tx *sql.Tx) (map[string]tc.CRConfigDeliveryService, error) {
dses := map[string]tc.CRConfigDeliveryService{}
admin := CDNSOAAdmin
expireSeconds := int(CDNSOAExpire / time.Second)
minimumSeconds := int(CDNSOAMinimum / time.Second)
refreshSeconds := int(CDNSOARefresh / time.Second)
retrySeconds := int(CDNSOARetry / time.Second)
if ttlOverride > 0 {
expireSeconds = int(math.Min(float64(ttlOverride), float64(expireSeconds)))
minimumSeconds = int(math.Min(float64(ttlOverride), float64(minimumSeconds)))
refreshSeconds = int(math.Min(float64(ttlOverride), float64(refreshSeconds)))
retrySeconds = int(math.Min(float64(ttlOverride), float64(retrySeconds)))
}
expireSecondsStr := strconv.Itoa(expireSeconds)
minimumSecondsStr := strconv.Itoa(minimumSeconds)
refreshSecondsStr := strconv.Itoa(refreshSeconds)
retrySecondsStr := strconv.Itoa(retrySeconds)
cdnSOA := &tc.SOA{
Admin: &admin,
ExpireSeconds: &expireSecondsStr,
MinimumSeconds: &minimumSecondsStr,
RefreshSeconds: &refreshSecondsStr,
RetrySeconds: &retrySecondsStr,
}
// Note the CRConfig omits acceptHTTP if it's true
falsePtr := false
protocol0 := &tc.CRConfigDeliveryServiceProtocol{AcceptHTTPS: false, RedirectOnHTTPS: false}
protocol1 := &tc.CRConfigDeliveryServiceProtocol{AcceptHTTP: &falsePtr, AcceptHTTPS: true, RedirectOnHTTPS: false}
protocol2 := &tc.CRConfigDeliveryServiceProtocol{AcceptHTTPS: true, RedirectOnHTTPS: false}
protocol3 := &tc.CRConfigDeliveryServiceProtocol{AcceptHTTPS: true, RedirectOnHTTPS: true}
protocolDefault := protocol0
geoProvider0 := GeoProviderMaxmindStr
geoProvider1 := GeoProviderNeustarStr
geoProviderDefault := geoProvider0
serverParams, err := getServerProfileParams(cdn, tx)
if err != nil {
return nil, errors.New("getting deliveryservice parameters: " + err.Error())
}
ttlOverrideDuration := time.Duration(ttlOverride) * time.Second
dsParams, err := getDSParams(serverParams)
if err != nil {
return nil, errors.New("getting deliveryservice server parameters: " + err.Error())
}
dsmatchsets, dsdomains, err := getDSRegexesDomains(cdn, domain, tx)
if err != nil {
return nil, errors.New("getting regex matchsets: " + err.Error())
}
staticDNSEntries, err := getStaticDNSEntries(cdn, tx)
if err != nil {
return nil, errors.New("getting static DNS entries: " + err.Error())
}
q := `
SELECT d.anonymous_blocking_enabled,
d.consistent_hash_regex,
d.deep_caching_type,
d.initial_dispersion,
d.dns_bypass_cname,
d.dns_bypass_ip,
d.dns_bypass_ip6,
d.dns_bypass_ttl,
(SELECT ARRAY_AGG(name ORDER BY name)
FROM deliveryservice_consistent_hash_query_param
WHERE deliveryservice_id = d.id) AS query_keys,
d.routing_name,
d.ccr_dns_ttl AS ttl,
d.ecs_enabled,
d.regional_geo_blocking,
d.geo_limit,
d.geo_limit_countries,
d.geolimit_redirect_url,
d.geo_provider,
d.http_bypass_fqdn,
d.ipv6_routing_enabled,
d.max_dns_answers,
d.miss_lat,
d.miss_long,
p.name AS profile,
d.protocol,
d.required_capabilities,
d.topology,
d.tr_request_headers,
d.tr_response_headers,
d.tr_response_headers,
t.name AS type,
d.xml_id
FROM deliveryservice AS d
INNER JOIN type AS t ON t.id = d.type
LEFT OUTER JOIN profile AS p ON p.id = d.profile
WHERE d.cdn_id = (select id FROM cdn WHERE name = $1)
AND d.active = $2
AND t.name != $3
`
rows, err := tx.Query(q, cdn, tc.DSActiveStateActive, tc.DSTypeAnyMap)
if err != nil {
return nil, errors.New("querying deliveryservices: " + err.Error())
}
defer rows.Close()
for rows.Next() {
ds := tc.CRConfigDeliveryService{
ConsistentHashQueryParams: []string{},
Protocol: &tc.CRConfigDeliveryServiceProtocol{},
ResponseHeaders: map[string]string{},
Soa: cdnSOA,
TTLs: &tc.CRConfigTTL{},
}
missLat := sql.NullFloat64{}
missLon := sql.NullFloat64{}
protocol := sql.NullInt64{}
ttl := sql.NullInt64{}
geoProvider := sql.NullInt64{}
ttype := ""
geoLimit := sql.NullInt64{}
geoLimitCountries := sql.NullString{}
geoLimitRedirectURL := sql.NullString{}
dispersion := sql.NullInt64{}
geoBlocking := false
trRespHdrsStr := sql.NullString{}
xmlID := ""
maxDNSAnswers := sql.NullInt64{}
profile := sql.NullString{}
dnsBypassIP := sql.NullString{}
dnsBypassIP6 := sql.NullString{}
dnsBypassTTL := sql.NullInt64{}
dnsBypassCName := sql.NullString{}
httpBypassFQDN := sql.NullString{}
ip6RoutingEnabled := sql.NullBool{}
ecsEnabled := sql.NullBool{}
deepCachingType := sql.NullString{}
trRequestHeaders := sql.NullString{}
trResponseHeaders := sql.NullString{}
anonymousBlocking := false
consistentHashRegex := sql.NullString{}
err := rows.Scan(
&anonymousBlocking,
&consistentHashRegex,
&deepCachingType,
&dispersion,
&dnsBypassCName,
&dnsBypassIP,
&dnsBypassIP6,
&dnsBypassTTL,
pq.Array(&ds.ConsistentHashQueryParams),
&ds.RoutingName,
&ds.TTL,
&ecsEnabled,
&geoBlocking,
&geoLimit,
&geoLimitCountries,
&geoLimitRedirectURL,
&geoProvider,
&httpBypassFQDN,
&ip6RoutingEnabled,
&maxDNSAnswers,
&missLat,
&missLon,
&profile,
&protocol,
pq.Array(&ds.RequiredCapabilities),
&ds.Topology,
&trRequestHeaders,
&trRespHdrsStr,
&trResponseHeaders,
&ttype,
&xmlID,
)
if err != nil {
return nil, errors.New("scanning deliveryservice: " + err.Error())
}
if ttlOverride > 0 && ds.TTL != nil {
*ds.TTL = int(math.Min(float64(ttlOverride), float64(*ds.TTL)))
}
// TODO prevent (lat XOR lon) in the Tx and UI
if missLat.Valid && missLon.Valid {
ds.MissLocation = &tc.CRConfigLatitudeLongitudeShort{Lat: missLat.Float64, Lon: missLon.Float64}
} else if missLat.Valid {
log.Warnln("delivery service " + xmlID + " has miss latitude but not longitude: omitting miss lat-lon from CRConfig")
} else if missLon.Valid {
log.Warnln("delivery service " + xmlID + " has miss longitude but not latitude: omitting miss lat-lon from CRConfig")
}
if ttl.Valid {
ttl := int(ttl.Int64)
ds.TTL = &ttl
}
protocolStr := tc.GetDSTypeCategory(ttype)
ds.Protocol = protocolDefault
if protocol.Valid {
switch protocol.Int64 {
case 0:
ds.Protocol = protocol0
case 1:
ds.Protocol = protocol1
case 2:
ds.Protocol = protocol2
case 3:
ds.Protocol = protocol3
}
}
ds.GeoLocationProvider = &geoProviderDefault
if geoProvider.Valid {
switch geoProvider.Int64 {
case 0:
ds.GeoLocationProvider = &geoProvider0
case 1:
ds.GeoLocationProvider = &geoProvider1
}
}
if ds.Protocol.AcceptHTTPS {
ds.SSLEnabled = true
}
if deepCachingType.Valid {
// TODO change to omit Valid check, default to the default DeepCachingType (NEVER). I'm pretty sure that's what should happen, but the Valid check emulates the old Perl CRConfig generation
t := tc.DeepCachingTypeFromString(deepCachingType.String)
ds.DeepCachingType = &t
}
ds.GeoLocationProvider = &geoProviderDefault
if matchsets, ok := dsmatchsets[xmlID]; ok {
ds.MatchSets = matchsets
} else {
log.Warnln("no regex matchsets for delivery service: " + xmlID)
}
if domains, ok := dsdomains[xmlID]; ok {
ds.Domains = domains
} else {
log.Warnln("no host regex for delivery service: " + xmlID)
}
switch geoLimit.Int64 { // No Valid check - default false and set countries, if null
case 0:
ds.CoverageZoneOnly = false
case 1:
ds.CoverageZoneOnly = true
if protocolStr == "HTTP" {
ds.GeoLimitRedirectURL = &geoLimitRedirectURL.String // No Valid check - empty string, if null
}
default:
ds.CoverageZoneOnly = false
if protocolStr == "HTTP" {
ds.GeoLimitRedirectURL = &geoLimitRedirectURL.String // No Valid check - empty string, if null
}
if geoLimitCountries.Valid {
for _, code := range strings.Split(geoLimitCountries.String, ",") {
ds.GeoEnabled = append(ds.GeoEnabled, tc.CRConfigGeoEnabled{CountryCode: strings.TrimSpace(code)})
}
}
}
nsSeconds := DefaultTLDTTLNS
soaSeconds := DefaultTLDTTLSOA
if profile.Valid {
if sval, ok := dsParams["tld.ttls.SOA"]; ok {
if val, err := strconv.Atoi(sval); err == nil {
soaSeconds = time.Duration(val) * time.Second
} else {
log.Errorln("delivery service " + xmlID + " profile " + profile.String + " param tld.ttls.SOA '" + sval + "' not a number - skipping")
}
}
if sval, ok := dsParams["tld.ttls.NS"]; ok {
if val, err := strconv.Atoi(sval); err == nil {
nsSeconds = time.Duration(val) * time.Second
} else {
log.Errorln("delivery service " + xmlID + " profile " + profile.String + " param tld.ttls.NS '" + sval + "' not a number - skipping")
}
}
}
if ttlOverride > 0 && ttlOverrideDuration < nsSeconds {
nsSeconds = ttlOverrideDuration
}
nsSecondsStr := strconv.Itoa(int(nsSeconds / time.Second))
if ttlOverride > 0 && ttlOverrideDuration < soaSeconds {
soaSeconds = ttlOverrideDuration
}
soaSecondsStr := strconv.Itoa(int(soaSeconds / time.Second))
ttlStr := ""
if ds.TTL != nil {
ttlStr = strconv.Itoa(*ds.TTL)
}
ds.TTLs = &tc.CRConfigTTL{
ASeconds: &ttlStr,
AAAASeconds: &ttlStr,
NSSeconds: &nsSecondsStr,
SOASeconds: &soaSecondsStr,
}
if protocolStr == "DNS" {
bypassDest := &tc.CRConfigBypassDestination{}
if dnsBypassIP.String != "" {
bypassDest.IP = &dnsBypassIP.String
}
if dnsBypassIP6.String != "" {
bypassDest.IP6 = &dnsBypassIP6.String
}
if dnsBypassTTL.Valid {
i := int(dnsBypassTTL.Int64)
if ttlOverride > 0 {
i = int(math.Min(float64(ttlOverride), float64(i)))
}
bypassDest.TTL = &i
}
if dnsBypassCName.Valid && dnsBypassCName.String != "" {
bypassDest.CName = &dnsBypassCName.String
}
if *bypassDest != (tc.CRConfigBypassDestination{}) {
if ds.BypassDestination == nil {
ds.BypassDestination = map[string]*tc.CRConfigBypassDestination{}
}
ds.BypassDestination["DNS"] = bypassDest
}
if maxDNSAnswers.Valid {
i := int(maxDNSAnswers.Int64)
ds.MaxDNSIPsForLocation = &i
}
} else if protocolStr == "HTTP" {
if httpBypassFQDN.String != "" {
if ds.BypassDestination == nil {
ds.BypassDestination = map[string]*tc.CRConfigBypassDestination{}
}
hostPort := strings.Split(httpBypassFQDN.String, ":")
bypass := &tc.CRConfigBypassDestination{FQDN: &hostPort[0]}
if len(hostPort) > 1 {
bypass.Port = &hostPort[1]
}
ds.BypassDestination["HTTP"] = bypass
}
geoBlockingStr := "false"
if geoBlocking {
geoBlockingStr = "true"
}
ds.RegionalGeoBlocking = &geoBlockingStr
anonymousBlockingStr := "false"
if anonymousBlocking {
anonymousBlockingStr = "true"
}
ds.AnonymousBlockingEnabled = &anonymousBlockingStr
if dispersion.Valid {
ds.Dispersion = &tc.CRConfigDispersion{Limit: int(dispersion.Int64), Shuffled: true}
}
}
if consistentHashRegex.Valid && consistentHashRegex.String != "" {
ds.ConsistentHashRegex = &consistentHashRegex.String
}
ds.IP6RoutingEnabled = &ip6RoutingEnabled.Bool // No Valid check, false if null
ds.EcsEnabled = &ecsEnabled.Bool // No Valid check, false if null
if trResponseHeaders.Valid && trResponseHeaders.String != "" {
trResponseHeaders.String = strings.Replace(trResponseHeaders.String, "__RETURN__", "\n", -1)
hdrs := strings.Split(trResponseHeaders.String, "\n")
for _, hdr := range hdrs {
nameVal := strings.Split(hdr, `:`)
name := strings.TrimSpace(nameVal[0])
val := ""
if len(nameVal) > 1 {
val = strings.Trim(nameVal[1], " \n\"")
}
ds.ResponseHeaders[name] = val
}
}
if trRequestHeaders.Valid && trRequestHeaders.String != "" {
trRequestHeaders.String = strings.Replace(trRequestHeaders.String, "__RETURN__", "\n", -1)
hdrs := strings.Split(trRequestHeaders.String, "\n")
for _, hdr := range hdrs {
nameVal := strings.Split(hdr, `:`)
name := strings.TrimSpace(nameVal[0])
ds.RequestHeaders = append(ds.RequestHeaders, name)
}
}
ds.StaticDNSEntries = staticDNSEntries[tc.DeliveryServiceName(xmlID)]
if ttlOverride > 0 {
for xmlID := range staticDNSEntries {
for index := range staticDNSEntries[xmlID] {
staticDNSEntries[xmlID][index].TTL = ttlOverride
}
}
}
dses[xmlID] = ds
}
if err := rows.Err(); err != nil {
return nil, errors.New("iterating deliveryservice rows: " + err.Error())
}
return dses, nil
}