1package api
2
3import (
4	"context"
5	"fmt"
6	"time"
7)
8
9// Partition is the configuration of a single admin partition. Admin Partitions are a Consul Enterprise feature.
10type Partition struct {
11	// Name is the name of the Partition.
12	Name string `json:"Name"`
13
14	// Description is where the user puts any information they want
15	// about the admin partition. It is not used internally.
16	Description string `json:"Description,omitempty"`
17
18	// DeletedAt is the time when the Partition was marked for deletion
19	// This is nullable so that we can omit if empty when encoding in JSON
20	DeletedAt *time.Time `json:"DeletedAt,omitempty" alias:"deleted_at"`
21
22	// CreateIndex is the Raft index at which the Partition was created
23	CreateIndex uint64 `json:"CreateIndex,omitempty"`
24
25	// ModifyIndex is the latest Raft index at which the Partition was modified.
26	ModifyIndex uint64 `json:"ModifyIndex,omitempty"`
27}
28
29// PartitionDefaultName is the default partition value.
30const PartitionDefaultName = "default"
31
32// Partitions can be used to manage Partitions in Consul Enterprise.
33type Partitions struct {
34	c *Client
35}
36
37// Operator returns a handle to the operator endpoints.
38func (c *Client) Partitions() *Partitions {
39	return &Partitions{c}
40}
41
42func (p *Partitions) Create(ctx context.Context, partition *Partition, q *WriteOptions) (*Partition, *WriteMeta, error) {
43	if partition.Name == "" {
44		return nil, nil, fmt.Errorf("Must specify a Name for Partition creation")
45	}
46
47	r := p.c.newRequest("PUT", "/v1/partition")
48	r.setWriteOptions(q)
49	r.ctx = ctx
50	r.obj = partition
51	rtt, resp, err := p.c.doRequest(r)
52	if err != nil {
53		return nil, nil, err
54	}
55	defer closeResponseBody(resp)
56	if err := requireOK(resp); err != nil {
57		return nil, nil, err
58	}
59
60	wm := &WriteMeta{RequestTime: rtt}
61	var out Partition
62	if err := decodeBody(resp, &out); err != nil {
63		return nil, nil, err
64	}
65
66	return &out, wm, nil
67}
68
69func (p *Partitions) Update(ctx context.Context, partition *Partition, q *WriteOptions) (*Partition, *WriteMeta, error) {
70	if partition.Name == "" {
71		return nil, nil, fmt.Errorf("Must specify a Name for Partition updating")
72	}
73
74	r := p.c.newRequest("PUT", "/v1/partition/"+partition.Name)
75	r.setWriteOptions(q)
76	r.ctx = ctx
77	r.obj = partition
78	rtt, resp, err := p.c.doRequest(r)
79	if err != nil {
80		return nil, nil, err
81	}
82	defer closeResponseBody(resp)
83	if err := requireOK(resp); err != nil {
84		return nil, nil, err
85	}
86
87	wm := &WriteMeta{RequestTime: rtt}
88	var out Partition
89	if err := decodeBody(resp, &out); err != nil {
90		return nil, nil, err
91	}
92
93	return &out, wm, nil
94}
95
96func (p *Partitions) Read(ctx context.Context, name string, q *QueryOptions) (*Partition, *QueryMeta, error) {
97	var out Partition
98	r := p.c.newRequest("GET", "/v1/partition/"+name)
99	r.setQueryOptions(q)
100	r.ctx = ctx
101	rtt, resp, err := p.c.doRequest(r)
102	if err != nil {
103		return nil, nil, err
104	}
105	defer closeResponseBody(resp)
106	found, resp, err := requireNotFoundOrOK(resp)
107	if err != nil {
108		return nil, nil, err
109	}
110
111	qm := &QueryMeta{}
112	parseQueryMeta(resp, qm)
113	qm.RequestTime = rtt
114
115	if !found {
116		return nil, qm, nil
117	}
118
119	if err := decodeBody(resp, &out); err != nil {
120		return nil, nil, err
121	}
122	return &out, qm, nil
123}
124
125func (p *Partitions) Delete(ctx context.Context, name string, q *WriteOptions) (*WriteMeta, error) {
126	r := p.c.newRequest("DELETE", "/v1/partition/"+name)
127	r.setWriteOptions(q)
128	r.ctx = ctx
129	rtt, resp, err := p.c.doRequest(r)
130	if err != nil {
131		return nil, err
132	}
133	defer closeResponseBody(resp)
134	if err := requireOK(resp); err != nil {
135		return nil, err
136	}
137
138	wm := &WriteMeta{RequestTime: rtt}
139	return wm, nil
140}
141
142func (p *Partitions) List(ctx context.Context, q *QueryOptions) ([]*Partition, *QueryMeta, error) {
143	var out []*Partition
144	r := p.c.newRequest("GET", "/v1/partitions")
145	r.setQueryOptions(q)
146	r.ctx = ctx
147	rtt, resp, err := p.c.doRequest(r)
148	if err != nil {
149		return nil, nil, err
150	}
151	defer closeResponseBody(resp)
152	if err := requireOK(resp); err != nil {
153		return nil, nil, err
154	}
155
156	qm := &QueryMeta{}
157	parseQueryMeta(resp, qm)
158	qm.RequestTime = rtt
159
160	if err := decodeBody(resp, &out); err != nil {
161		return nil, nil, err
162	}
163	return out, qm, nil
164}
165