consul/api/resource.go

127 lines
3.1 KiB
Go
Raw Normal View History

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package api
import (
"fmt"
"net/http"
"strings"
"github.com/hashicorp/consul/proto-public/pbresource"
)
type Resource struct {
c *Client
}
type GVK struct {
Group string
Version string
Kind string
}
type WriteRequest struct {
Metadata map[string]string `json:"metadata"`
Data map[string]any `json:"data"`
Owner *pbresource.ID `json:"owner"`
}
type WriteResponse struct {
Metadata map[string]string `json:"metadata"`
Data map[string]any `json:"data"`
Owner *pbresource.ID `json:"owner,omitempty"`
ID *pbresource.ID `json:"id"`
Version string `json:"version"`
Generation string `json:"generation"`
Status map[string]any `json:"status"`
}
type ListResponse struct {
Resources []WriteResponse `json:"resources"`
}
// Config returns a handle to the Config endpoints
func (c *Client) Resource() *Resource {
return &Resource{c}
}
func (resource *Resource) Read(gvk *GVK, resourceName string, q *QueryOptions) (map[string]interface{}, error) {
r := resource.c.newRequest("GET", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName)))
r.setQueryOptions(q)
_, resp, err := resource.c.doRequest(r)
if err != nil {
return nil, err
}
defer closeResponseBody(resp)
if err := requireOK(resp); err != nil {
return nil, err
}
var out map[string]interface{}
if err := decodeBody(resp, &out); err != nil {
return nil, err
}
return out, nil
}
func (resource *Resource) Delete(gvk *GVK, resourceName string, q *QueryOptions) error {
r := resource.c.newRequest("DELETE", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName)))
r.setQueryOptions(q)
_, resp, err := resource.c.doRequest(r)
if err != nil {
return err
}
defer closeResponseBody(resp)
if err := requireHttpCodes(resp, http.StatusNoContent); err != nil {
return err
}
return nil
}
func (resource *Resource) Apply(gvk *GVK, resourceName string, q *QueryOptions, payload *WriteRequest) (*WriteResponse, *WriteMeta, error) {
url := strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName))
r := resource.c.newRequest("PUT", url)
r.setQueryOptions(q)
r.obj = payload
rtt, resp, err := resource.c.doRequest(r)
if err != nil {
return nil, nil, err
}
defer closeResponseBody(resp)
if err := requireOK(resp); err != nil {
return nil, nil, err
}
wm := &WriteMeta{}
wm.RequestTime = rtt
var out *WriteResponse
if err := decodeBody(resp, &out); err != nil {
return nil, nil, err
}
return out, wm, nil
}
func (resource *Resource) List(gvk *GVK, q *QueryOptions) (*ListResponse, error) {
r := resource.c.newRequest("GET", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind)))
r.setQueryOptions(q)
_, resp, err := resource.c.doRequest(r)
if err != nil {
return nil, err
}
defer closeResponseBody(resp)
if err := requireOK(resp); err != nil {
return nil, err
}
var out *ListResponse
if err := decodeBody(resp, &out); err != nil {
return nil, err
}
return out, nil
}