feat: Integrate with Report v2 in the go app for the Example API.
For more information, see https://cloud.google.com/service-infrastructure/docs/service-control/reference/rest/v2/services/report. PiperOrigin-RevId: 343146007
This commit is contained in:
parent
2cda8d285b
commit
f1e0ce4dbc
|
|
@ -19,15 +19,12 @@ import (
|
|||
|
||||
// Check calls Service Control API v2 for admission control.
|
||||
// Name specifies the target resource name. Permission specifies
|
||||
// the required permission on the target resource.
|
||||
func check(w http.ResponseWriter, r *http.Request, name string, permission string) (string, error) {
|
||||
client, err := servicecontrol.NewService(r.Context())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// the required permission on the target resource. Received
|
||||
// specifies the timestamp when the request is received.
|
||||
func check(w http.ResponseWriter, r *http.Request, name string, permission string, received time.Time, client *servicecontrol.Service) (string, error) {
|
||||
// Construct CheckRequest from the incoming HTTP request.
|
||||
// The code assumes the incoming request processed by App Engine ingress.
|
||||
checkRequest := &servicecontrol.CheckRequest{
|
||||
req := &servicecontrol.CheckRequest{
|
||||
ServiceConfigId: "latest",
|
||||
Attributes: &servicecontrol.AttributeContext{
|
||||
Origin: &servicecontrol.Peer{
|
||||
|
|
@ -41,7 +38,7 @@ func check(w http.ResponseWriter, r *http.Request, name string, permission strin
|
|||
},
|
||||
Request: &servicecontrol.Request{
|
||||
Id: r.Header.Get("x-appengine-request-log-id"),
|
||||
Time: time.Now().UTC().Format(time.RFC3339),
|
||||
Time: received.UTC().Format(time.RFC3339),
|
||||
Method: r.Method,
|
||||
Scheme: r.Header.Get("x-forwarded-proto"),
|
||||
Host: r.Host,
|
||||
|
|
@ -53,6 +50,9 @@ func check(w http.ResponseWriter, r *http.Request, name string, permission strin
|
|||
"referer": r.Header.Get("referer"),
|
||||
},
|
||||
},
|
||||
Resource: &servicecontrol.Resource{
|
||||
Name: name,
|
||||
},
|
||||
},
|
||||
Resources: []*servicecontrol.ResourceInfo{
|
||||
{
|
||||
|
|
@ -62,18 +62,64 @@ func check(w http.ResponseWriter, r *http.Request, name string, permission strin
|
|||
},
|
||||
},
|
||||
}
|
||||
response, err := client.Services.Check("endpointsapis.appspot.com", checkRequest).Do()
|
||||
resp, err := client.Services.Check("endpointsapis.appspot.com", req).Do()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
responseJSON, err := response.MarshalJSON()
|
||||
json, err := resp.MarshalJSON()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(responseJSON), nil
|
||||
return string(json), nil
|
||||
}
|
||||
|
||||
func admission(w http.ResponseWriter, r *http.Request) (string, error) {
|
||||
// Report calls Service Control API v2 for telemetry reporting.
|
||||
// Name specifies the target resource name. ResponseCode specifies
|
||||
// the response code returned to user. Received specifies the
|
||||
// timestamp when the request is received.
|
||||
func report(w http.ResponseWriter, r *http.Request, name string, responseCode int64, received time.Time, client *servicecontrol.Service) (string, error) {
|
||||
// Construct ReportRequest from the incoming HTTP request.
|
||||
// The code assumes the incoming request processed by App Engine ingress.
|
||||
req := &servicecontrol.ReportRequest{
|
||||
ServiceConfigId: "latest",
|
||||
Operations: []*servicecontrol.AttributeContext{
|
||||
{
|
||||
Api: &servicecontrol.Api{
|
||||
Service: "endpointsapis.appspot.com",
|
||||
Operation: "google.example.endpointsapis.v1.Workspaces.GetWorkspace",
|
||||
Version: "v1",
|
||||
Protocol: r.Header.Get("x-forwarded-proto"),
|
||||
},
|
||||
Request: &servicecontrol.Request{
|
||||
Size: r.ContentLength,
|
||||
Time: received.UTC().Format(time.RFC3339),
|
||||
},
|
||||
Response: &servicecontrol.Response{
|
||||
Time: time.Now().UTC().Format(time.RFC3339),
|
||||
Code: responseCode,
|
||||
Headers: map[string]string{
|
||||
"x-backend-latency": "0.007",
|
||||
},
|
||||
},
|
||||
Destination: &servicecontrol.Peer{
|
||||
RegionCode: "us-central1",
|
||||
},
|
||||
Resource: &servicecontrol.Resource{
|
||||
Name: name,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := client.Services.Report("endpointsapis.appspot.com", req).Do()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "{}", nil
|
||||
}
|
||||
|
||||
// Parse processes the request path and extract the resource name and
|
||||
// permissions.
|
||||
func parse(r *http.Request) (string, string, error) {
|
||||
// Split the request path.
|
||||
segments := strings.Split(r.URL.Path, "/")
|
||||
|
||||
|
|
@ -81,25 +127,45 @@ func admission(w http.ResponseWriter, r *http.Request) (string, error) {
|
|||
// "/v1/projects/*/locations/*/workspaces". They correspond to the
|
||||
// GetWorkspace() and ListWorkspaces() methods defined in ../v1/workspace.proto.
|
||||
if segments[0] != "" || segments[1] != "v1" || segments[2] != "projects" || segments[4] != "locations" || segments[6] != "workspaces" || len(segments) > 8 {
|
||||
return "", errors.New("Resource '" + r.URL.Path + "' not found.")
|
||||
return "", "", errors.New("Resource '" + r.URL.Path + "' not found.")
|
||||
}
|
||||
|
||||
// Skip prefix "/v1/".
|
||||
resource := r.URL.Path[4:]
|
||||
permission := "endpointsapis.appspot.com/workspaces.list"
|
||||
if len(segments) == 8 {
|
||||
permission = "endpointsapis.appspot.com/workspaces.get"
|
||||
}
|
||||
return check(w, r, resource, permission)
|
||||
return resource, permission, nil
|
||||
}
|
||||
|
||||
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Perform admission control.
|
||||
result, err := admission(w, r)
|
||||
received := time.Now()
|
||||
|
||||
// Create a client for Service Control API v2.
|
||||
client, err := servicecontrol.NewService(r.Context())
|
||||
if err != nil {
|
||||
fmt.Fprintln(w, "Error:")
|
||||
fmt.Fprintln(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resource, permission, err := parse(r)
|
||||
if err != nil {
|
||||
fmt.Fprintln(w, "Error:")
|
||||
fmt.Fprintln(w, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Perform admission control.
|
||||
result, err := check(w, r, resource, permission, received, client)
|
||||
|
||||
var responseCode int64 = 200
|
||||
// Print the admission control result.
|
||||
if err != nil {
|
||||
fmt.Fprintln(w, "Error:")
|
||||
fmt.Fprintln(w, err.Error())
|
||||
responseCode = 403
|
||||
} else {
|
||||
fmt.Fprintln(w, "CheckResponse:")
|
||||
fmt.Fprintln(w, result)
|
||||
|
|
@ -116,6 +182,9 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
|
|||
fmt.Fprintf(w, "%v: %v\n", key, value)
|
||||
}
|
||||
}
|
||||
|
||||
// Perform telemetry report.
|
||||
report(w, r, resource, responseCode, received, client)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue