You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by el...@apache.org on 2018/07/06 17:22:51 UTC
[trafficcontrol] 01/02: Add TO Go deliveryservices/servers/eligible
This is an automated email from the ASF dual-hosted git repository.
elsloo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
commit faa010c4f99b6e0fdbe0a720e2ca885250b8cb24
Author: Robert Butts <ro...@apache.org>
AuthorDate: Wed Jun 20 17:43:23 2018 -0600
Add TO Go deliveryservices/servers/eligible
---
.../deliveryservice/deliveryservicesv12.go | 13 ++
.../traffic_ops_golang/deliveryservice/eligible.go | 189 +++++++++++++++++++++
traffic_ops/traffic_ops_golang/routes.go | 1 +
3 files changed, 203 insertions(+)
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
index a84a14f..d80b7b1 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
@@ -88,6 +88,19 @@ func getDSTenantIDByID(tx *sql.Tx, id int) (*int, bool, error) {
return tenantID, true, nil
}
+// GetDSTenantIDByIDTx returns the tenant ID, whether the delivery service exists, and any error.
+// Note the id may be nil, even if true is returned, if the delivery service exists but its tenant_id field is null.
+func GetDSTenantIDByIDTx(tx *sql.Tx, id int) (*int, bool, error) {
+ tenantID := (*int)(nil)
+ if err := tx.QueryRow(`SELECT tenant_id FROM deliveryservice where id = $1`, id).Scan(&tenantID); err != nil {
+ if err == sql.ErrNoRows {
+ return nil, false, nil
+ }
+ return nil, false, fmt.Errorf("querying tenant ID for delivery service ID '%v': %v", id, err)
+ }
+ return tenantID, true, nil
+}
+
// getDSTenantIDByName returns the tenant ID, whether the delivery service exists, and any error.
// Note the id may be nil, even if true is returned, if the delivery service exists but its tenant_id field is null.
func getDSTenantIDByName(tx *sql.Tx, name string) (*int, bool, error) {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go b/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
new file mode 100644
index 0000000..494e4c7
--- /dev/null
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/eligible.go
@@ -0,0 +1,189 @@
+package deliveryservice
+
+/*
+ * 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 (
+ "database/sql"
+ "errors"
+ "net/http"
+ "strconv"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
+)
+
+func GetServersEligible(w http.ResponseWriter, r *http.Request) {
+ inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"id"}, []string{"id"})
+ if userErr != nil || sysErr != nil {
+ api.HandleErr(w, r, errCode, userErr, sysErr)
+ return
+ }
+ defer inf.Close()
+
+ // TODO create a helper function to check all this in a single line.
+ ok, err := tenant.IsTenancyEnabledTx(inf.Tx.Tx)
+ if err != nil {
+ api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenancy enabled: "+err.Error()))
+ return
+ }
+ if ok {
+ dsTenantID, ok, err := GetDSTenantIDByIDTx(inf.Tx.Tx, inf.IntParams["id"])
+ if err != nil {
+ api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ }
+ if !ok {
+ api.HandleErr(w, r, http.StatusNotFound, errors.New("delivery service "+inf.Params["id"]+" not found"), nil)
+ return
+ }
+ if dsTenantID != nil {
+ if authorized, err := tenant.IsResourceAuthorizedToUserTx(*dsTenantID, inf.User, inf.Tx.Tx); err != nil {
+ api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("checking tenant: "+err.Error()))
+ return
+ } else if !authorized {
+ api.HandleErr(w, r, http.StatusForbidden, errors.New("not authorized on this tenant"), nil)
+ return
+ }
+ }
+ }
+
+ servers, err := getEligibleServers(inf.Tx.Tx, inf.IntParams["id"])
+ if err != nil {
+ api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("getting eligible servers: "+err.Error()))
+ return
+ }
+ api.WriteResp(w, r, servers)
+}
+
+const JumboFrameBPS = 9000
+
+func getEligibleServers(tx *sql.Tx, dsID int) ([]tc.DSServer, error) {
+ q := `
+WITH ds_id as (SELECT $1::bigint as v)
+SELECT
+cg.name as cachegroup,
+s.cachegroup as cachegroup_id,
+s.cdn_id,
+cdn.name as cdn_name,
+s.domain_name,
+s.guid,
+s.host_name,
+s.https_port,
+s.id,
+s.ilo_ip_address,
+s.ilo_ip_gateway,
+s.ilo_ip_netmask,
+s.ilo_password,
+s.ilo_username,
+COALESCE(s.interface_mtu, ` + strconv.Itoa(JumboFrameBPS) + `) as interface_mtu,
+s.interface_name,
+s.ip6_address,
+s.ip6_gateway,
+s.ip_address,
+s.ip_gateway,
+s.ip_netmask,
+s.last_updated,
+s.mgmt_ip_address,
+s.mgmt_ip_gateway,
+s.mgmt_ip_netmask,
+s.offline_reason,
+pl.name as phys_location,
+s.phys_location as phys_location_id,
+p.name as profile,
+p.description as profile_desc,
+s.profile as profile_id,
+s.rack,
+s.router_host_name,
+s.router_port_name,
+st.name as status,
+s.status as status_id,
+s.tcp_port,
+t.name as server_type,
+s.type as server_type_id,
+s.upd_pending as upd_pending
+FROM server s
+JOIN cachegroup cg ON s.cachegroup = cg.id
+JOIN cdn cdn ON s.cdn_id = cdn.id
+JOIN phys_location pl ON s.phys_location = pl.id
+JOIN profile p ON s.profile = p.id
+JOIN status st ON s.status = st.id
+JOIN type t ON s.type = t.id
+WHERE s.cdn_id = (SELECT cdn_id from deliveryservice where id = (select v from ds_id))
+AND (t.name LIKE 'EDGE%' OR t.name LIKE 'ORG%')
+`
+ rows, err := tx.Query(q, dsID)
+ if err != nil {
+ return nil, errors.New("querying delivery service eligible servers: " + err.Error())
+ }
+ defer rows.Close()
+
+ servers := []tc.DSServer{}
+ for rows.Next() {
+ s := tc.DSServer{}
+ err := rows.Scan(
+ &s.Cachegroup,
+ &s.CachegroupID,
+ &s.CDNID,
+ &s.CDNName,
+ &s.DomainName,
+ &s.GUID,
+ &s.HostName,
+ &s.HTTPSPort,
+ &s.ID,
+ &s.ILOIPAddress,
+ &s.ILOIPGateway,
+ &s.ILOIPNetmask,
+ &s.ILOPassword,
+ &s.ILOUsername,
+ &s.InterfaceMtu,
+ &s.InterfaceName,
+ &s.IP6Address,
+ &s.IP6Gateway,
+ &s.IPAddress,
+ &s.IPGateway,
+ &s.IPNetmask,
+ &s.LastUpdated,
+ &s.MgmtIPAddress,
+ &s.MgmtIPGateway,
+ &s.MgmtIPNetmask,
+ &s.OfflineReason,
+ &s.PhysLocation,
+ &s.PhysLocationID,
+ &s.Profile,
+ &s.ProfileDesc,
+ &s.ProfileID,
+ &s.Rack,
+ &s.RouterHostName,
+ &s.RouterPortName,
+ &s.Status,
+ &s.StatusID,
+ &s.TCPPort,
+ &s.Type,
+ &s.TypeID,
+ &s.UpdPending,
+ )
+ if err != nil {
+ return nil, errors.New("scanning delivery service eligible servers: " + err.Error())
+ }
+ servers = append(servers, s)
+ }
+ return servers, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index cd6b623..c33e666 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -355,6 +355,7 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
{1.1, http.MethodPut, `deliveryservices/{id}/?(\.json)?$`, deliveryservice.UpdateV12(), auth.PrivLevelOperations, Authenticated, nil},
{1.3, http.MethodDelete, `deliveryservices/{id}/?(\.json)?$`, api.DeleteHandler(deliveryservice.GetTypeV13Factory()), auth.PrivLevelOperations, Authenticated, nil},
{1.1, http.MethodDelete, `deliveryservices/{id}/?(\.json)?$`, api.DeleteHandler(deliveryservice.GetTypeV12Factory()), auth.PrivLevelOperations, Authenticated, nil},
+ {1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible/?(\.json)?$`, deliveryservice.GetServersEligible, auth.PrivLevelReadOnly, Authenticated, nil},
//System
{1.1, http.MethodGet, `system/info/?(\.json)?$`, systeminfo.Handler(d.DB), auth.PrivLevelReadOnly, Authenticated, nil},