ocket8888 commented on a change in pull request #5179:
URL: https://github.com/apache/trafficcontrol/pull/5179#discussion_r583764036
##########
File path: traffic_ops/traffic_ops_golang/routing/routes.go
##########
@@ -355,6 +356,11 @@ func Routes(d ServerData) ([]Route, []RawRoute,
http.Handler, error) {
{api.Version{4, 0}, http.MethodPost, `coordinates/?$`,
api.CreateHandler(&coordinate.TOCoordinate{}), auth.PrivLevelOperations,
Authenticated, nil, 44281121573},
{api.Version{4, 0}, http.MethodDelete, `coordinates/?$`,
api.DeleteHandler(&coordinate.TOCoordinate{}), auth.PrivLevelOperations,
Authenticated, nil, 43038498893},
+ //CDN notification
+ {api.Version{4, 0}, http.MethodGet, `cdn_notifications/?$`,
cdnnotification.Read, auth.PrivLevelReadOnly, Authenticated, nil, 2221224514},
+ {api.Version{4, 0}, http.MethodPost, `cdn_notifications`,
cdnnotification.Create, auth.PrivLevelOperations, Authenticated, nil,
2765223513},
Review comment:
This one can't end with a `/`? why not? Should be anchored with a `$`
either way - we've had that introduce weird bugs in the past when that wasn't
done.
##########
File path: traffic_ops/traffic_ops_golang/cdnnotification/cdnnotifications.go
##########
@@ -0,0 +1,191 @@
+package cdnnotification
+
+/*
+ * 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"
+ "fmt"
+ "net/http"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+ "github.com/apache/trafficcontrol/lib/go-util"
+ "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
+
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
+)
+
+const readQuery = `
+SELECT cn.cdn,
+ cn.last_updated,
+ cn.user,
+ cn.notification
+FROM cdn_notification as cn
+INNER JOIN cdn ON cdn.name = cn.cdn
+INNER JOIN tm_user ON tm_user.username = cn.user
+`
+
+const insertQuery = `
+INSERT INTO cdn_notification (cdn, "user", notification)
+VALUES ($1, $2, $3)
+RETURNING cdn_notification.cdn,
+ cdn_notification.last_updated,
+ cdn_notification.user,
+ cdn_notification.notification
+`
+
+const deleteQuery = `
+DELETE FROM cdn_notification
+WHERE cdn_notification.cdn = $1
+RETURNING cdn_notification.cdn,
+ cdn_notification.last_updated,
+ cdn_notification.user,
+ cdn_notification.notification
+`
+
+// Read is the handler for GET requests to /cdn_notifications.
+func Read(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()
+
+ cdnNotifications := []tc.CDNNotification{}
+
+ queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
+ "cdn": dbhelpers.WhereColumnInfo{"cdn.name", nil},
+ "user": dbhelpers.WhereColumnInfo{"tm_user.username", nil},
+ }
+
+ where, orderBy, pagination, queryValues, errs :=
dbhelpers.BuildWhereAndOrderByAndPagination(inf.Params, queryParamsToQueryCols)
+ if len(errs) > 0 {
+ sysErr = util.JoinErrs(errs)
+ errCode = http.StatusBadRequest
+ api.HandleErr(w, r, tx, errCode, nil, sysErr)
+ return
+ }
+
+ query := readQuery + where + orderBy + pagination
+ rows, err := inf.Tx.NamedQuery(query, queryValues)
+ if err != nil {
+ userErr, sysErr, errCode = api.ParseDBError(err)
+ if sysErr != nil {
+ sysErr = fmt.Errorf("notification read query: %v",
sysErr)
+ }
+
+ api.HandleErr(w, r, tx, errCode, userErr, sysErr)
+ return
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ var n tc.CDNNotification
+ if err = rows.Scan(&n.CDN, &n.LastUpdated, &n.User,
&n.Notification); err != nil {
+ api.HandleErr(w, r, tx, http.StatusInternalServerError,
nil, errors.New("scanning cdn notifications: "+err.Error()))
+ return
+ }
+ cdnNotifications = append(cdnNotifications, n)
+ }
+
+ api.WriteResp(w, r, cdnNotifications)
+}
+
+// Create is the handler for POST requests to /cdn_notifications.
+func Create(w http.ResponseWriter, r *http.Request) {
+ inf, sysErr, userErr, errCode := api.NewInfo(r, nil, nil)
+ tx := inf.Tx.Tx
+ if sysErr != nil || userErr != nil {
+ api.HandleErr(w, r, tx, errCode, userErr, sysErr)
+ return
+ }
+ defer inf.Close()
+
+ var req tc.CDNNotificationRequest
+ if userErr = api.Parse(r.Body, tx, &req); userErr != nil {
+ api.HandleErr(w, r, tx, http.StatusBadRequest, userErr, nil)
+ return
+ }
+
+ var resp tc.CDNNotification
+ err := tx.QueryRow(insertQuery, req.CDN, inf.User.UserName,
req.Notification).Scan(&resp.CDN, &resp.LastUpdated, &resp.User,
&resp.Notification)
+ if err != nil {
+ userErr, sysErr, errCode = api.ParseDBError(err)
+ api.HandleErr(w, r, tx, errCode, userErr, sysErr)
+ return
+ }
+
+ changeLogMsg := fmt.Sprintf("CDN_NOTIFICATION: %s, CDN: %s, ACTION:
Created", *resp.Notification, resp.CDN)
+ api.CreateChangeLogRawTx(api.ApiChange, changeLogMsg, inf.User, tx)
+
+ alertMsg := fmt.Sprintf("CDN notification created [ User = %s ] for
CDN: %s", resp.User, resp.CDN)
+ api.WriteRespAlertObj(w, r, tc.SuccessLevel, alertMsg, resp)
Review comment:
creation should use a `201 Created` response code and ideally set a
`Location` header with to a request path where the new object representation
can be fetched.
##########
File path: lib/go-tc/cdn_notification.go
##########
@@ -0,0 +1,59 @@
+package tc
+
+/*
+ * 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"
+ "time"
+
+ "github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
+ "github.com/apache/trafficcontrol/lib/go-util"
+
+ "github.com/go-ozzo/ozzo-validation"
+)
+
+// CDNNotificationsResponse is a list of CDN notifications as a response.
+type CDNNotificationsResponse struct {
+ Response []CDNNotification `json:"response"`
+ Alerts
+}
+
+// CDNNotificationRequest encodes the request data for the POST
+// cdn_notifications endpoint.
+type CDNNotificationRequest struct {
+ CDN string `json:"cdn"`
+ Notification string `json:"notification"`
+}
+
+// CDNNotification is a notification created for a specific CDN
Review comment:
GoDoc should end with a period
##########
File path: traffic_ops/v4-client/cdn_notifications.go
##########
@@ -0,0 +1,50 @@
+/*
+
+ Licensed 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.
+*/
+
+package client
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+const (
+ API_CDN_NOTIFICATIONS = apiBase + "/cdn_notifications"
+)
+
+// GetCDNNotificationsWithHdr returns a list of CDN Notifications.
+func (to *Session) GetCDNNotificationsWithHdr(cdnName string, header
http.Header) ([]tc.CDNNotification, ReqInf, error) {
+ var data tc.CDNNotificationsResponse
+ route := fmt.Sprintf("%s?cdn=%s", API_CDN_NOTIFICATIONS, cdnName)
+ reqInf, err := to.get(route, header, &data)
+ return data.Response, reqInf, err
+}
+
+// CreateCDNNotification creates a CDN notification.
+func (to *Session) CreateCDNNotification(notification
tc.CDNNotificationRequest) (tc.Alerts, ReqInf, error) {
+ var alerts tc.Alerts
+ reqInf, err := to.post(API_CDN_NOTIFICATIONS, notification, nil,
&alerts)
+ return alerts, reqInf, err
+}
+
+// DeleteCDNNotification deletes a CDN Notification by CDN name.
+func (to *Session) DeleteCDNNotification(cdnName string) (tc.Alerts, ReqInf,
error) {
+ route := fmt.Sprintf("%s?cdn=%s", API_CDN_NOTIFICATIONS, cdnName)
Review comment:
cdnName should be properly encoded. I think `net/url` exports some way
to do that besides putting it in a `Values` and using its `Encode` method, but
I can't remember for sure.
##########
File path: traffic_ops/v4-client/cdn_notifications.go
##########
@@ -0,0 +1,50 @@
+/*
+
+ Licensed 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.
+*/
+
+package client
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+const (
+ API_CDN_NOTIFICATIONS = apiBase + "/cdn_notifications"
+)
+
+// GetCDNNotificationsWithHdr returns a list of CDN Notifications.
+func (to *Session) GetCDNNotificationsWithHdr(cdnName string, header
http.Header) ([]tc.CDNNotification, ReqInf, error) {
Review comment:
This doesn't need to include `WithHdr` - there's no alternative without
a header. You might also consider just allowing a `net/url.Values` instead of
`cdnName`, so that the endpoint's full functionality is exposed, including
pagination and sorting.
##########
File path: traffic_ops/v4-client/cdn_notifications.go
##########
@@ -0,0 +1,50 @@
+/*
+
+ Licensed 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.
+*/
+
+package client
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/apache/trafficcontrol/lib/go-tc"
+)
+
+const (
+ API_CDN_NOTIFICATIONS = apiBase + "/cdn_notifications"
+)
+
+// GetCDNNotificationsWithHdr returns a list of CDN Notifications.
+func (to *Session) GetCDNNotificationsWithHdr(cdnName string, header
http.Header) ([]tc.CDNNotification, ReqInf, error) {
+ var data tc.CDNNotificationsResponse
+ route := fmt.Sprintf("%s?cdn=%s", API_CDN_NOTIFICATIONS, cdnName)
Review comment:
This also needs to be encoded
----------------------------------------------------------------
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]