rob05c commented on a change in pull request #3688: Add TO Go remap.config
URL: https://github.com/apache/trafficcontrol/pull/3688#discussion_r329274357
 
 

 ##########
 File path: traffic_ops/traffic_ops_golang/ats/db.go
 ##########
 @@ -197,3 +346,428 @@ WHERE
        }
        return params, nil
 }
+
+func GetServerParamData(tx *sql.Tx, profileID int, configFile string, 
serverHost string, serverDomain string) (map[string]string, error) {
+       qry := `
+SELECT
+  p.id,
+  p.name,
+  p.value
+FROM
+  parameter p
+  join profile_parameter pp on p.id = pp.parameter
+  JOIN profile pr on p.id = pp.profile
+WHERE
+  pr.id = $1
+  AND p.config_file = $2
+`
+       rows, err := tx.Query(qry, profileID, configFile)
+       if err != nil {
+               return nil, errors.New("querying: " + err.Error())
+       }
+       defer rows.Close()
+
+       params := map[string]string{}
+       for rows.Next() {
+               id := 0
+               name := ""
+               val := ""
+               if err := rows.Scan(&name, &val); err != nil {
+                       return nil, errors.New("scanning: " + err.Error())
+               }
+               if name == "location" {
+                       continue
+               }
+
+               // some files have multiple lines with the same key... handle 
that with param id.
+               key := name
+               if _, ok := params[name]; ok {
+                       key += "__" + strconv.Itoa(id)
+               }
+               if val == "STRING __HOSTNAME__" {
+                       val = serverHost + "." + serverDomain
+               }
+               params[key] = val
+       }
+       return params, nil
+}
+
+type DSData struct {
+       Type       tc.DSType
+       OriginFQDN *string
+}
+
+func GetDSData(tx *sql.Tx, serverID int) ([]DSData, error) {
+       qry := `
+SELECT
+  dstype.name AS ds_type,
+  (SELECT o.protocol::text || \'://\' || o.fqdn || rtrim(concat(\':\', 
o.port::text), \':\')
+    FROM origin o
+    WHERE o.deliveryservice = ds.id
+    AND o.is_primary) as org_server_fqdn
+FROM
+  deliveryservice ds
+  JOIN type as dstype ON ds.type = dstype.id
+WHERE
+  ds.id IN (
+    SELECT DISTINCT deliveryservice
+    FROM deliveryservice_server
+    WHERE server = $1
+  )
+`
+       rows, err := tx.Query(qry, serverID)
+       if err != nil {
+               return nil, errors.New("querying: " + err.Error())
+       }
+       defer rows.Close()
+
+       dses := []DSData{}
+       for rows.Next() {
+               d := DSData{}
+               if err := rows.Scan(&d.Type, &d.OriginFQDN); err != nil {
+                       return nil, errors.New("scanning: " + err.Error())
+               }
+               d.Type = tc.DSTypeFromString(string(d.Type))
+               dses = append(dses, d)
+       }
+       return dses, nil
+}
+
+func GetRemapDSData(tx *sql.Tx, serverInfo *atscfg.ServerInfo) 
([]atscfg.RemapConfigDSData, error) {
+       if tc.CacheTypeFromString(serverInfo.Type) == tc.CacheTypeMid {
+               return GetRemapDSDataForMid(tx, serverInfo)
+       } else {
+               return GetRemapDSDataForEdge(tx, serverInfo)
+       }
+}
+
+const RemapDSDataQuerySelectFrom = `
+SELECT
+  ds.xml_id,
+  ds.id AS ds_id,
+  ds.dscp,
+  ds.routing_name,
+  ds.signing_algorithm,
+  ds.qstring_ignore,
+  (SELECT o.protocol::text || '://' || o.fqdn || rtrim(concat(':', 
o.port::text), ':')
+    FROM origin o
+    WHERE o.deliveryservice = ds.id
+    AND o.is_primary) as org_server_fqdn,
+  ds.multi_site_origin,
+  ds.range_request_handling,
+  ds.fq_pacing_rate,
+  ds.origin_shield,
+  r.pattern,
+  retype.name AS re_type,
+  dstype.name AS ds_type,
+  cdn.domain_name AS domain_name,
+  dsr.set_number,
+  ds.edge_header_rewrite,
+  ds.mid_header_rewrite,
+  ds.regex_remap,
+  ds.cacheurl,
+  ds.remap_text,
+  ds.protocol,
+  ds.profile,
+  ds.anonymous_blocking_enabled,
+  ds.active
+FROM
+  deliveryservice ds
+  JOIN deliveryservice_regex dsr ON dsr.deliveryservice = ds.id
+  JOIN regex r ON dsr.regex = r.id
+  JOIN type retype ON r.type = retype.id
+  JOIN type dstype ON ds.type = dstype.id
+  JOIN cdn ON cdn.id = ds.cdn_id
+`
+
+const RemapDSDataQueryWhereForMid = `
+WHERE
+  cdn.name = $1
+  AND ds.id in (SELECT dss.deliveryservice FROM deliveryservice_server dss)
+  AND ds.active = true
+`
+
+const RemapDSDataQueryWhereForEdge = `
+JOIN deliveryservice_server dss ON dss.deliveryservice = ds.id
+WHERE dss.server = $1
+`
+
+const RemapDSDataQueryOrderBy = `
+ORDER BY
+  ds_id,
+  re_type,
+  set_number
+`
+
+func GetRemapDSDataForMid(tx *sql.Tx, serverInfo *atscfg.ServerInfo) 
([]atscfg.RemapConfigDSData, error) {
+       qry := RemapDSDataQuerySelectFrom + RemapDSDataQueryWhereForMid + 
RemapDSDataQueryOrderBy
+       rows, err := tx.Query(qry, serverInfo.CDN)
+       if err != nil {
+               return nil, errors.New("querying: " + err.Error())
+       }
+       defer rows.Close()
+
+       dses := []atscfg.RemapConfigDSData{}
+       for rows.Next() {
+               d := atscfg.RemapConfigDSData{}
+               if err := rows.Scan(&d.Name, &d.ID, &d.DSCP, &d.RoutingName, 
&d.SigningAlgorithm, &d.QStringIgnore, &d.OriginFQDN, &d.MultiSiteOrigin, 
&d.RangeRequestHandling, &d.FQPacingRate, &d.OriginShield, &d.Pattern, 
&d.RegexType, &d.Type, &d.Domain, &d.RegexSetNumber, &d.EdgeHeaderRewrite, 
&d.MidHeaderRewrite, &d.RegexRemap, &d.CacheURL, &d.RemapText, &d.Protocol, 
&d.ProfileID, &d.AnonymousBlockingEnabled, &d.Active); err != nil {
+                       return nil, errors.New("scanning: " + err.Error())
+               }
+               if !RemapDotConfigIncludeInactiveDeliveryServices && !d.Active {
+                       continue
+               }
+               d.Type = tc.DSTypeFromString(string(d.Type))
+               dses = append(dses, d)
+       }
+       return dses, nil
+}
+
+func GetRemapDSDataForEdge(tx *sql.Tx, server *atscfg.ServerInfo) 
([]atscfg.RemapConfigDSData, error) {
+       qry := RemapDSDataQuerySelectFrom + RemapDSDataQueryWhereForEdge + 
RemapDSDataQueryOrderBy
+       rows, err := tx.Query(qry, server.ID)
+       if err != nil {
+               return nil, errors.New("querying: " + err.Error())
+       }
+       defer rows.Close()
+
+       dses := []atscfg.RemapConfigDSData{}
+       for rows.Next() {
+               d := atscfg.RemapConfigDSData{}
+               if err := rows.Scan(&d.Name, &d.ID, &d.DSCP, &d.RoutingName, 
&d.SigningAlgorithm, &d.QStringIgnore, &d.OriginFQDN, &d.MultiSiteOrigin, 
&d.RangeRequestHandling, &d.FQPacingRate, &d.OriginShield, &d.Pattern, 
&d.RegexType, &d.Type, &d.Domain, &d.RegexSetNumber, &d.EdgeHeaderRewrite, 
&d.MidHeaderRewrite, &d.RegexRemap, &d.CacheURL, &d.RemapText, &d.Protocol, 
&d.ProfileID, &d.AnonymousBlockingEnabled, &d.Active); err != nil {
+                       return nil, errors.New("scanning: " + err.Error())
+               }
+               if !RemapDotConfigIncludeInactiveDeliveryServices && !d.Active {
+                       continue
+               }
+               d.Type = tc.DSTypeFromString(string(d.Type))
+               dses = append(dses, d)
+       }
+       return dses, nil
+}
+
+func GetServerNameFromID(tx *sql.Tx, id int) (tc.CacheName, bool, error) {
+       qry := `SELECT s.host_name FROM server s WHERE s.id = $1`
+       name := tc.CacheName("")
+       if err := tx.QueryRow(qry, id).Scan(&name); err != nil {
+               if err == sql.ErrNoRows {
+                       return "", false, nil
+               }
+               return "", false, errors.New("querying: " + err.Error())
+       }
+       return name, true, nil
+}
+
+// getServerNameFromNameOrID returns the server name from a parameter which 
may be the name or ID.
+// This also checks and verifies the existence of the given server, and 
returns an appropriate user error if it doesn't exist.
+// Returns the name, any user error, any system error, and any error code.
+func GetServerNameFromNameOrID(tx *sql.Tx, serverNameOrID string) 
(tc.CacheName, error, error, int) {
+       if serverID, err := strconv.Atoi(serverNameOrID); err == nil {
+               serverName, ok, err := dbhelpers.GetServerNameFromID(tx, 
int64(serverID))
+               if err != nil {
+                       return "", nil, fmt.Errorf("getting server name from id 
%v: %v", serverID, err), http.StatusInternalServerError
+               } else if !ok {
+                       return "", errors.New("server not found"), nil, 
http.StatusNotFound
+               }
+               return tc.CacheName(serverName), nil, nil, http.StatusOK
+       }
+
+       serverName := tc.CacheName(serverNameOrID)
+       if ok, err := dbhelpers.ServerExists(string(serverName), tx); err != 
nil {
+               return "", nil, fmt.Errorf("checking server name '%v' 
existence: %v", serverName, err), http.StatusInternalServerError
+       } else if !ok {
+               return "", errors.New("server not found"), nil, 
http.StatusNotFound
+       }
+       return serverName, nil, nil, http.StatusOK
+}
+
+// getServerInfo returns the necessary info about the server, whether the 
server exists, and any error.
+func GetServerInfoByID(tx *sql.Tx, id int) (*atscfg.ServerInfo, bool, error) {
+       return getServerInfo(tx, ServerInfoQuery()+`WHERE s.id = $1`, 
[]interface{}{id})
+}
+
+// getServerInfo returns the necessary info about the server, whether the 
server exists, and any error.
+func GetServerInfoByHost(tx *sql.Tx, host tc.CacheName) (*atscfg.ServerInfo, 
bool, error) {
+       return getServerInfo(tx, ServerInfoQuery()+` WHERE s.host_name = $1 `, 
[]interface{}{host})
+}
+
+// getServerInfo returns the necessary info about the server, whether the 
server exists, and any error.
+func getServerInfo(tx *sql.Tx, qry string, qryParams []interface{}) 
(*atscfg.ServerInfo, bool, error) {
+       s := atscfg.ServerInfo{}
+       if err := tx.QueryRow(qry, qryParams...).Scan(&s.CDN, &s.CDNID, &s.ID, 
&s.HostName, &s.DomainName, &s.IP, &s.ProfileID, &s.ProfileName, &s.Port, 
&s.HTTPSPort, &s.Type, &s.CacheGroupID, &s.ParentCacheGroupID, 
&s.SecondaryParentCacheGroupID, &s.ParentCacheGroupType, 
&s.SecondaryParentCacheGroupType); err != nil {
+               if err == sql.ErrNoRows {
+                       return nil, false, nil
+               }
+               return nil, false, errors.New("querying server info: " + 
err.Error())
+       }
+       return &s, true, nil
+}
+
+func ServerInfoQuery() string {
+       return `
+SELECT
+  c.name as cdn,
+  s.cdn_id,
+  s.id,
+  s.host_name,
+  c.domain_name,
+  s.ip_address,
+  s.profile AS profile_id,
+  p.name AS profile_name,
+  s.tcp_port,
+  s.https_port,
+  t.name as type,
+  s.cachegroup,
+  COALESCE(cg.parent_cachegroup_id, ` + strconv.Itoa(atscfg.InvalidID) + `) as 
parent_cachegroup_id,
+  COALESCE(cg.secondary_parent_cachegroup_id, ` + 
strconv.Itoa(atscfg.InvalidID) + `) as secondary_parent_cachegroup_id,
+  COALESCE(parentt.name, '') as parent_cachegroup_type,
+  COALESCE(sparentt.name, '') as secondary_parent_cachegroup_type
+FROM
+  server s
+  JOIN cdn c ON s.cdn_id = c.id
+  JOIN type t ON s.type = t.id
+  JOIN profile p ON p.id = s.profile
+  JOIN cachegroup cg on s.cachegroup = cg.id
+  LEFT JOIN type parentt on parentt.id = (select type from cachegroup where id 
= cg.parent_cachegroup_id)
+  LEFT JOIN type sparentt on sparentt.id = (select type from cachegroup where 
id = cg.secondary_parent_cachegroup_id)
+`
+}
+
+// GetATSMajorVersion returns the major version of the given profile's package 
trafficserver parameter.
+// If no parameter exists, this does not return an error, but rather logs a 
warning and uses DefaultATSVersion.
+func GetATSMajorVersion(tx *sql.Tx, serverProfileID atscfg.ProfileID) (int, 
error) {
+       atsVersion, _, err := GetProfileParamValue(tx, int(serverProfileID), 
"package", "trafficserver")
+       if err != nil {
+               return 0, errors.New("getting profile param value: " + 
err.Error())
+       }
+       if len(atsVersion) == 0 {
+               atsVersion = atscfg.DefaultATSVersion
+               log.Warnln("Parameter package.trafficserver missing for profile 
" + strconv.Itoa(int(serverProfileID)) + ". Assuming version " + atsVersion)
+       }
+       atsMajorVer, err := strconv.Atoi(atsVersion[:1])
 
 Review comment:
   Done. Put it in a func, including unit tests verifying correctness.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to