This is an automated email from the ASF dual-hosted git repository. rob pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-trafficcontrol.git
commit bfa8ae4aa27771b0f5967639e8b6a6258b83ccea Author: ASchmidt <andrew_schm...@comcast.com> AuthorDate: Mon May 7 11:35:15 2018 -0600 started adding new read method --- lib/go-tc/deliveryservice_servers.go | 62 ++++ .../servers/deliveryservicestoServer.go | 359 --------------------- traffic_ops/traffic_ops_golang/routes.go | 3 + 3 files changed, 65 insertions(+), 359 deletions(-) diff --git a/lib/go-tc/deliveryservice_servers.go b/lib/go-tc/deliveryservice_servers.go index aa0ec99..85bfde9 100644 --- a/lib/go-tc/deliveryservice_servers.go +++ b/lib/go-tc/deliveryservice_servers.go @@ -78,3 +78,65 @@ type DssServer struct { TypeID *int `json:"typeId" db:"server_type_id"` UpdPending *bool `json:"updPending" db:"upd_pending"` } + +// DeliveryServiceNullable - a version of the deliveryservice that allows for all fields to be null +type DssDeliveryService struct { + // NOTE: the db: struct tags are used for testing to map to their equivalent database column (if there is one) + // + Active *bool `json:"active" db:"active"` + CacheURL *string `json:"cacheurl" db:"cacheurl"` + CCRDNSTTL *int `json:"ccrDnsTtl" db:"ccr_dns_ttl"` + CDNID *int `json:"cdnId" db:"cdn_id"` + CDNName *string `json:"cdnName"` + CheckPath *string `json:"checkPath" db:"check_path"` + DeepCachingType *DeepCachingType `json:"deepCachingType" db:"deep_caching_type"` + DisplayName *string `json:"displayName" db:"display_name"` + DNSBypassCNAME *string `json:"dnsBypassCname" db:"dns_bypass_cname"` + DNSBypassIP *string `json:"dnsBypassIp" db:"dns_bypass_ip"` + DNSBypassIP6 *string `json:"dnsBypassIp6" db:"dns_bypass_ip6"` + DNSBypassTTL *int `json:"dnsBypassTtl" db:"dns_bypass_ttl"` + DSCP *int `json:"dscp" db:"dscp"` + EdgeHeaderRewrite *string `json:"edgeHeaderRewrite" db:"edge_header_rewrite"` + FQPacingRate *int `json:"fqPacingRate" db:"fq_pacing_rate"` + GeoLimit *int `json:"geoLimit" db:"geo_limit"` + GeoLimitCountries *string `json:"geoLimitCountries" db:"geo_limit_countries"` + GeoLimitRedirectURL *string `json:"geoLimitRedirectURL" db:"geolimit_redirect_url"` + GeoProvider *int `json:"geoProvider" db:"geo_provider"` + GlobalMaxMBPS *int `json:"globalMaxMbps" db:"global_max_mbps"` + GlobalMaxTPS *int `json:"globalMaxTps" db:"global_max_tps"` + HTTPBypassFQDN *string `json:"httpBypassFqdn" db:"http_bypass_fqdn"` + ID *int `json:"id" db:"id"` + InfoURL *string `json:"infoUrl" db:"info_url"` + InitialDispersion *int `json:"initialDispersion" db:"initial_dispersion"` + IPV6RoutingEnabled *bool `json:"ipv6RoutingEnabled" db:"ipv6_routing_enabled"` + LastUpdated *TimeNoMod `json:"lastUpdated" db:"last_updated"` + LogsEnabled *bool `json:"logsEnabled" db:"logs_enabled"` + LongDesc *string `json:"longDesc" db:"long_desc"` + LongDesc1 *string `json:"longDesc1" db:"long_desc_1"` + LongDesc2 *string `json:"longDesc2" db:"long_desc_2"` + MaxDNSAnswers *int `json:"maxDnsAnswers" db:"max_dns_answers"` + MidHeaderRewrite *string `json:"midHeaderRewrite" db:"mid_header_rewrite"` + MissLat *float64 `json:"missLat" db:"miss_lat"` + MissLong *float64 `json:"missLong" db:"miss_long"` + MultiSiteOrigin *bool `json:"multiSiteOrigin" db:"multi_site_origin"` + OriginShield *string `json:"originShield" db:"origin_shield"` + OrgServerFQDN *string `json:"orgServerFqdn" db:"org_server_fqdn"` + ProfileDesc *string `json:"profileDescription"` + ProfileID *int `json:"profileId" db:"profile"` + ProfileName *string `json:"profileName"` + Protocol *int `json:"protocol" db:"protocol"` + QStringIgnore *int `json:"qstringIgnore" db:"qstring_ignore"` + RangeRequestHandling *int `json:"rangeRequestHandling" db:"range_request_handling"` + RegexRemap *string `json:"regexRemap" db:"regex_remap"` + RegionalGeoBlocking *bool `json:"regionalGeoBlocking" db:"regional_geo_blocking"` + RemapText *string `json:"remapText" db:"remap_text"` + RoutingName *string `json:"routingName" db:"routing_name"` + SigningAlgorithm *string `json:"signingAlgorithm" db:"signing_algorithm"` + SSLKeyVersion *int `json:"sslKeyVersion" db:"ssl_key_version"` + TRRequestHeaders *string `json:"trRequestHeaders" db:"tr_request_headers"` + TRResponseHeaders *string `json:"trResponseHeaders" db:"tr_response_headers"` + TenantID *int `json:"tenantId" db:"tenant_id"` + TypeName *string `json:"typeName"` + TypeID *int `json:"typeId" db:"type"` + XMLID *string `json:"xmlId" db:"xml_id"` +} diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go deleted file mode 100644 index 768dab0..0000000 --- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/deliveryservicestoServer.go +++ /dev/null @@ -1,359 +0,0 @@ -package servers - -/* - * 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" - "strconv" - - "github.com/apache/incubator-trafficcontrol/lib/go-log" - "github.com/apache/incubator-trafficcontrol/lib/go-tc" - "github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/api" - "github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/auth" - "github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers" - "github.com/apache/incubator-trafficcontrol/traffic_ops/traffic_ops_golang/tovalidate" - "github.com/go-ozzo/ozzo-validation" - - "github.com/jmoiron/sqlx" - "github.com/lib/pq" -) - -// TODeliveryServiceRequest provides a type alias to define functions on -type TODeliveryServiceServer tc.DeliveryServiceServer - -//the refType is passed into the handlers where a copy of its type is used to decode the json. -var refType = TODeliveryServiceServer(tc.DeliveryServiceServer{}) - -func GetRefType() *TODeliveryServiceServer { - return &refType -} - -/* -# get all delivery services associated with a server (from deliveryservice_server table) -$r->get( "/api/$version/servers/:id/deliveryservices" => [ id => qr/\d+/ ] )->over( authenticated => 1, not_ldap => 1 )->to( 'Deliveryservice#get_deliveryservices_by_serverId', namespace => $namespace ); - -# delivery service / server assignments -$r->post("/api/$version/deliveryservices/:xml_id/servers")->over( authenticated => 1, not_ldap => 1 ) -->to( 'Deliveryservice#assign_servers', namespace => $namespace ); -$r->delete("/api/$version/deliveryservice_server/:dsId/:serverId" => [ dsId => qr/\d+/, serverId => qr/\d+/ ] )->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#remove_server_from_ds', namespace => $namespace ); - # -- DELIVERYSERVICES: SERVERS - # Supports ?orderby=key - $r->get("/api/$version/deliveryserviceserver")->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#index', namespace => $namespace ); - $r->post("/api/$version/deliveryserviceserver")->over( authenticated => 1, not_ldap => 1 )->to( 'DeliveryServiceServer#assign_servers_to_ds', namespace => $namespace ); - - {1.2, http.MethodGet, `deliveryservices/{id}/servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil}, - {1.2, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil}, - {1.2, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil}, - -*/ - -func (dss TODeliveryServiceServer) GetKeyFieldsInfo() []api.KeyFieldInfo { - return []api.KeyFieldInfo{{"deliveryservice", api.GetIntKey}, {"server", api.GetIntKey}} -} - -//Implementation of the Identifier, Validator interface functions -func (dss TODeliveryServiceServer) GetKeys() (map[string]interface{}, bool) { - if dss.DeliveryService == nil { - return map[string]interface{}{"deliveryservice": 0}, false - } - if dss.Server == nil { - return map[string]interface{}{"server": 0}, false - } - keys := make(map[string]interface{}) - ds_id := *dss.DeliveryService - server_id := *dss.Server - - keys["deliveryservice"] = ds_id - keys["server"] = server_id - return keys, true -} - -func (dss *TODeliveryServiceServer) GetAuditName() string { - if dss.DeliveryService != nil { - return strconv.Itoa(*dss.DeliveryService) + "-" + strconv.Itoa(*dss.Server) - } - return "unknown" -} - -func (dss *TODeliveryServiceServer) GetType() string { - return "deliveryserviceServers" -} - -func (dss *TODeliveryServiceServer) SetKeys(keys map[string]interface{}) { - ds_id, _ := keys["deliveryservice"].(int) //this utilizes the non panicking type assertion, if the thrown away ok variable is false i will be the zero of the type, 0 here. - dss.DeliveryService = &ds_id - - server_id, _ := keys["server"].(int) //this utilizes the non panicking type assertion, if the thrown away ok variable is false i will be the zero of the type, 0 here. - dss.Server = &server_id -} - -// Validate fulfills the api.Validator interface -func (dss *TODeliveryServiceServer) Validate(db *sqlx.DB) []error { - - errs := validation.Errors{ - "deliveryservice": validation.Validate(dss.DeliveryService, validation.Required), - "server": validation.Validate(dss.Server, validation.Required), - } - - return tovalidate.ToErrors(errs) -} - -//The TODeliveryServiceServer implementation of the Creator interface -//all implementations of Creator should use transactions and return the proper errorType -//ParsePQUniqueConstraintError is used to determine if a profileparameter with conflicting values exists -//if so, it will return an errorType of DataConflict and the type should be appended to the -//generic error message returned -//The insert sql returns the profile and lastUpdated values of the newly inserted profileparameter and have -//to be added to the struct -func (dss *TODeliveryServiceServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) { - rollbackTransaction := true - tx, err := db.Beginx() - defer func() { - if tx == nil || !rollbackTransaction { - return - } - err := tx.Rollback() - if err != nil { - log.Errorln(errors.New("rolling back transaction: " + err.Error())) - } - }() - - if err != nil { - log.Error.Printf("could not begin transaction: %v", err) - return tc.DBError, tc.SystemError - } - resultRows, err := tx.NamedQuery(insertQuery(), dss) - if err != nil { - if pqErr, ok := err.(*pq.Error); ok { - err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr) - if eType == tc.DataConflictError { - return errors.New("a parameter with " + err.Error()), eType - } - return err, eType - } - log.Errorf("received non pq error: %++v from create execution", err) - return tc.DBError, tc.SystemError - } - defer resultRows.Close() - - var ds_id int - var server_id int - var lastUpdated tc.TimeNoMod - rowsAffected := 0 - for resultRows.Next() { - rowsAffected++ - if err := resultRows.Scan(&ds_id, &server_id, &lastUpdated); err != nil { - log.Error.Printf("could not scan dss from insert: %s\n", err) - return tc.DBError, tc.SystemError - } - } - if rowsAffected == 0 { - err = errors.New("no deliveryServiceServer was inserted, nothing to return") - log.Errorln(err) - return tc.DBError, tc.SystemError - } - if rowsAffected > 1 { - err = errors.New("too many ids returned from parameter insert") - log.Errorln(err) - return tc.DBError, tc.SystemError - } - - dss.SetKeys(map[string]interface{}{"deliveryservice": ds_id, "server": server_id}) - dss.LastUpdated = &lastUpdated - err = tx.Commit() - if err != nil { - log.Errorln("Could not commit transaction: ", err) - return tc.DBError, tc.SystemError - } - rollbackTransaction = false - return nil, tc.NoError -} - -func insertQuery() string { - query := `INSERT INTO deliveryservice_server ( -deliveryservice, -server) VALUES ( -:ds_id, -:server_id) RETURNING deliveryservice, server, last_updated` - return query -} - -func (dss *TODeliveryServiceServer) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) { - idstr, ok := params["id"] - - if !ok { - log.Errorf("Deliveryservice Server Id missing") - return nil, []error{errors.New("Deliverservice id is required.")}, tc.DataMissingError - } - id, err := strconv.Atoi(idstr) - - if err != nil { - log.Errorf("Deliveryservice Server Id is not an integer") - return nil, []error{errors.New("Deliverservice id is not an integer.")}, tc.SystemError - } - - query := selectQuery() - log.Debugln("Query is ", query) - - rows, err := db.Queryx(query, id) - if err != nil { - log.Errorf("Error querying DeliveryserviceServers: %v", err) - return nil, []error{tc.DBError}, tc.SystemError - } - defer rows.Close() - - servers := []interface{}{} - for rows.Next() { - var s tc.DssServer - if err = rows.StructScan(&s); err != nil { - log.Errorf("error parsing dss rows: %v", err) - return nil, []error{tc.DBError}, tc.SystemError - } - hiddenField := "" - if user.PrivLevel < auth.PrivLevelAdmin { - s.ILOPassword = &hiddenField - } - servers = append(servers, s) - } - - return servers, []error{}, tc.NoError - -} - -//The Parameter implementation of the Deleter interface -//all implementations of Deleter should use transactions and return the proper errorType -func (dss *TODeliveryServiceServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) { - rollbackTransaction := true - tx, err := db.Beginx() - defer func() { - if tx == nil || !rollbackTransaction { - return - } - err := tx.Rollback() - if err != nil { - log.Errorln(errors.New("rolling back transaction: " + err.Error())) - } - }() - - if err != nil { - log.Error.Printf("could not begin transaction: %v", err) - return tc.DBError, tc.SystemError - } - log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), dss) - result, err := tx.NamedExec(deleteQuery(), dss) - if err != nil { - log.Errorf("received error: %++v from delete execution", err) - return tc.DBError, tc.SystemError - } - rowsAffected, err := result.RowsAffected() - if err != nil { - return tc.DBError, tc.SystemError - } - if rowsAffected < 1 { - return errors.New("no parameter with that id found"), tc.DataMissingError - } - if rowsAffected > 1 { - return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError - } - - err = tx.Commit() - if err != nil { - log.Errorln("Could not commit transaction: ", err) - return tc.DBError, tc.SystemError - } - rollbackTransaction = false - return nil, tc.NoError -} -func selectQuery() string { - - const JumboFrameBPS = 9000 - - // COALESCE is needed to default values that are nil in the database - // because Go does not allow that to marshal into the struct - selectStmt := `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.id in (select server from deliveryservice_server where deliveryservice = $1)` - - return selectStmt -} - -func updateQuery() string { - query := `UPDATE - profile_parameter SET - profile=:profile_id, - parameter=:parameter_id - WHERE profile=:profile_id AND - parameter = :parameter_id - RETURNING last_updated` - return query -} - -func deleteQuery() string { - query := `DELETE FROM profile_parameter - WHERE profile=:profile_id and parameter=:parameter_id` - return query -} diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go index ebe3ca3..e6efb81 100644 --- a/traffic_ops/traffic_ops_golang/routes.go +++ b/traffic_ops/traffic_ops_golang/routes.go @@ -164,6 +164,9 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) { // get all edge servers associated with a delivery service (from deliveryservice_server table) {1.1, http.MethodGet, `deliveryservices/{id}/servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil}, + {1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(serverdss.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil}, + {1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil}, + //{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, api.ReadHandler(dsserver.GetRefType(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil}, //Server {1.1, http.MethodGet, `servers/checks$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}}, -- To stop receiving notification emails like this one, please contact r...@apache.org.