File: response.go

package info (click to toggle)
incus 6.0.5-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 24,428 kB
  • sloc: sh: 16,313; ansic: 3,121; python: 457; makefile: 337; ruby: 51; sql: 50; lisp: 6
file content (119 lines) | stat: -rw-r--r-- 2,692 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package operations

import (
	"fmt"
	"net/http"

	"github.com/lxc/incus/v6/internal/server/response"
	localUtil "github.com/lxc/incus/v6/internal/server/util"
	"github.com/lxc/incus/v6/internal/version"
	"github.com/lxc/incus/v6/shared/api"
	"github.com/lxc/incus/v6/shared/logger"
)

// Operation response.
type operationResponse struct {
	op *Operation
}

// OperationResponse returns an operation response.
func OperationResponse(op *Operation) response.Response {
	return &operationResponse{op}
}

func (r *operationResponse) Render(w http.ResponseWriter) error {
	err := r.op.Start()
	if err != nil {
		return err
	}

	url, md, err := r.op.Render()
	if err != nil {
		return err
	}

	body := api.ResponseRaw{
		Type:       api.AsyncResponse,
		Status:     api.OperationCreated.String(),
		StatusCode: int(api.OperationCreated),
		Operation:  url,
		Metadata:   md,
	}

	w.Header().Set("Location", url)

	w.WriteHeader(http.StatusAccepted)

	var debugLogger logger.Logger
	if debug {
		debugLogger = logger.AddContext(logger.Ctx{"http_code": http.StatusAccepted})
	}

	return localUtil.WriteJSON(w, body, debugLogger)
}

func (r *operationResponse) String() string {
	_, md, err := r.op.Render()
	if err != nil {
		return fmt.Sprintf("error: %s", err)
	}

	return md.ID
}

// Code returns the HTTP code.
func (r *operationResponse) Code() int {
	return http.StatusAccepted
}

// Forwarded operation response.
//
// Returned when the operation has been created on another node.
type forwardedOperationResponse struct {
	op      *api.Operation
	project string
}

// ForwardedOperationResponse creates a response that forwards the metadata of
// an operation created on another node.
func ForwardedOperationResponse(project string, op *api.Operation) response.Response {
	return &forwardedOperationResponse{
		op:      op,
		project: project,
	}
}

func (r *forwardedOperationResponse) Render(w http.ResponseWriter) error {
	url := fmt.Sprintf("/%s/operations/%s", version.APIVersion, r.op.ID)
	if r.project != "" {
		url += fmt.Sprintf("?project=%s", r.project)
	}

	body := api.ResponseRaw{
		Type:       api.AsyncResponse,
		Status:     api.OperationCreated.String(),
		StatusCode: int(api.OperationCreated),
		Operation:  url,
		Metadata:   r.op,
	}

	w.Header().Set("Location", url)

	w.WriteHeader(http.StatusAccepted)

	var debugLogger logger.Logger
	if debug {
		debugLogger = logger.AddContext(logger.Ctx{"http_code": http.StatusAccepted})
	}

	return localUtil.WriteJSON(w, body, debugLogger)
}

func (r *forwardedOperationResponse) String() string {
	return r.op.ID
}

// Code returns the HTTP code.
func (r *forwardedOperationResponse) Code() int {
	return http.StatusAccepted
}