mhoppa commented on a change in pull request #4015: Rewrite /federations to Go 
- POST/PUT/DELETE
URL: https://github.com/apache/trafficcontrol/pull/4015#discussion_r339808566
 
 

 ##########
 File path: traffic_ops/traffic_ops_golang/federations/federations.go
 ##########
 @@ -167,3 +206,296 @@ ORDER BY
        }
        return feds, nil
 }
+
+// AddFederationResorverMappingsForCurrentUser is the handler for a POST 
request to /federations.
+// Confusingly, it does not create a federation, but is instead used to 
manipulate the resolvers
+// used by one or more particular Delivery Services for one or more particular 
Federations.
+func AddFederationResolverMappingsForCurrentUser(w http.ResponseWriter, r 
*http.Request) {
+       inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
+       tx := inf.Tx.Tx
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
+               return
+       }
+       defer inf.Close()
+
+       mappings, userErr, sysErr := getMappingsFromRequestBody(*inf.Version, 
r.Body)
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, tx, http.StatusBadRequest, userErr, sysErr)
+               return
+       }
+
+       if err := mappings.Validate(tx); err != nil {
+               errCode = http.StatusBadRequest
+               userErr = fmt.Errorf("validating request: %v", err)
+               api.HandleErr(w, r, tx, errCode, userErr, nil)
+               return
+       }
+
+       userErr, sysErr, errCode = 
addFederationResolverMappingsForCurrentUser(inf.User, tx, mappings)
+       if userErr != nil || sysErr != nil {
+               api.HandleErr(w, r, tx, errCode, userErr, sysErr)
+               return
+       }
+
+       msg := fmt.Sprintf("%s successfully created federation resolvers.", 
inf.User.UserName)
+       if inf.Version.Minor <= 3 {
+               api.WriteResp(w, r, msg)
+       } else {
+               api.WriteRespAlertObj(w, r, tc.SuccessLevel, msg, msg)
+       }
+}
+
+// handles the main logic of the POST handler, separated out for convenience
+func addFederationResolverMappingsForCurrentUser(u *auth.CurrentUser, tx 
*sql.Tx, mappings []tc.DeliveryServiceFederationResolverMapping) (error, error, 
int) {
+       for _, fed := range mappings {
+               dsTenant, ok, err := dbhelpers.GetDSTenantIDFromXMLID(tx, 
fed.DeliveryService)
+               if err != nil {
+                       return nil, err, http.StatusInternalServerError
+               } else if !ok {
+                       return fmt.Errorf("'%s' - no such Delivery Service", 
fed.DeliveryService), nil, http.StatusConflict
+               }
+
+               if ok, err = tenant.IsResourceAuthorizedToUserTx(dsTenant, u, 
tx); err != nil {
+                       err = fmt.Errorf("Checking user #%d tenancy permissions 
on DS '%s' (tenant #%d)", u.ID, fed.DeliveryService, dsTenant)
+                       return nil, err, http.StatusInternalServerError
+               } else if !ok {
+                       userErr := fmt.Errorf("'%s' - no such Delivery 
Service", fed.DeliveryService)
+                       sysErr := fmt.Errorf("User '%s' requested unauthorized 
federation resolver mapping modification on the '%s' Delivery Service", 
u.UserName, fed.DeliveryService)
+                       return userErr, sysErr, http.StatusConflict
+               }
+
+               fedID, ok, err := dbhelpers.GetFederationIDForUserIDByXMLID(tx, 
u.ID, fed.DeliveryService)
+               if err != nil {
+                       return nil, fmt.Errorf("Getting Federation ID: %v", 
err), http.StatusInternalServerError
+               } else if !ok {
+                       err = fmt.Errorf("No federation(s) found for user %s on 
delivery service '%s'.", u.UserName, fed.DeliveryService)
+                       return err, nil, http.StatusConflict
+               }
+
+               inserted, err := 
addFederationResolverMappingsToFederation(fed.Mappings, fed.DeliveryService, 
fedID, tx)
+               if err != nil {
+                       err = fmt.Errorf("Adding federation resolver mapping(s) 
to federation: %v", err)
+                       return nil, err, http.StatusInternalServerError
+               }
+
+               changelogMsg := "FEDERATION DELIVERY SERVICE: %s, ID: %d, 
ACTION: User %s successfully added federation resolvers [ %s ]"
+               changelogMsg = fmt.Sprintf(changelogMsg, fed.DeliveryService, 
fedID, u.UserName, inserted)
+               api.CreateChangeLogRawTx(api.ApiChange, changelogMsg, u, tx)
+       }
+       return nil, nil, http.StatusOK
+}
+
+// adds federation resolver mappings for a particular delivery service to a 
given federation, creating said resolvers if
+// they don't already exist.
+func addFederationResolverMappingsToFederation(res tc.ResolverMapping, xmlid 
string, fed uint, tx *sql.Tx) (string, error) {
+       var resp string
+       if len(res.Resolve4) > 0 {
+               inserted, err := addFederationResolver(res.Resolve4, 
tc.FederationResolverType4, fed, tx)
+               if err != nil {
+                       return "", err
+               }
+               resp = strings.Join(inserted, ", ")
+       }
+       if len(res.Resolve6) > 0 {
+               inserted, err := addFederationResolver(res.Resolve6, 
tc.FederationResolverType6, fed, tx)
+               if err != nil {
+                       return "", err
+               }
+               resp += strings.Join(inserted, ", ")
+       }
+       return resp, nil
+}
+
+// adds federation resolvers of a specific type to the given federation
+func addFederationResolver(res []string, t tc.FederationResolverType, fedID 
uint, tx *sql.Tx) ([]string, error) {
+       inserted := []string{}
+       for _, r := range res {
+               var ip string
+               var id uint
+               if err := tx.QueryRow(insertResolverQuery, r, t).Scan(&ip, 
&id); err != nil && err != sql.ErrNoRows {
+                       return nil, err
+               }
+               if ip != "" && id > 0 {
 
 Review comment:
   what would it mean if the ip is equal to "" and the id less than zero? Would 
that ever happen do we need to check for it? 

----------------------------------------------------------------
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:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to