-
Notifications
You must be signed in to change notification settings - Fork 5
/
iplists.go
240 lines (201 loc) · 7.51 KB
/
iplists.go
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package illumioapi
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"strconv"
"strings"
)
// IPRange repsents one of the IP ranges of an IP List.
type IPRange struct {
Description string `json:"description,omitempty"`
Exclusion bool `json:"exclusion,omitempty"`
FromIP string `json:"from_ip,omitempty"`
ToIP string `json:"to_ip,omitempty"`
}
// FQDN represents an FQDN in an IPList
type FQDN struct {
FQDN string `json:"fqdn"`
}
// IPList represents an IP List in the Illumio PCE.
type IPList struct {
CreatedAt string `json:"created_at,omitempty"`
CreatedBy *CreatedBy `json:"created_by,omitempty"`
DeletedAt string `json:"deleted_at,omitempty"`
DeletedBy *DeletedBy `json:"deleted_by,omitempty"`
Description string `json:"description,omitempty"`
ExternalDataReference string `json:"external_data_reference,omitempty"`
ExternalDataSet string `json:"external_data_set,omitempty"`
FQDNs *[]*FQDN `json:"fqdns,omitempty"`
Href string `json:"href,omitempty"`
IPRanges *[]*IPRange `json:"ip_ranges,omitempty"`
Name string `json:"name,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
UpdatedBy *UpdatedBy `json:"updated_by,omitempty"`
Size int `json:"size,omitempty"`
}
// GetIPList queries returns the IP List based on name. Provisioned IP lists checked before draft
func (p *PCE) GetIPList(name string, provStatus string) (IPList, APIResponse, error) {
var ipList IPList
var api APIResponse
var ipLists []IPList
// Validate pStatus
provStatus = strings.ToLower(provStatus)
if provStatus != "active" && provStatus != "draft" {
return ipList, api, fmt.Errorf("get iplist - invalid provStatus")
}
// Active IP Lists
apiURL, err := url.Parse("https://" + pceSanitization(p.FQDN) + ":" + strconv.Itoa(p.Port) + "/api/v2/orgs/" + strconv.Itoa(p.Org) + "/sec_policy/" + provStatus + "/ip_lists")
if err != nil {
return ipList, api, fmt.Errorf("get iplist - %s", err)
}
q := apiURL.Query()
q.Set("name", name)
apiURL.RawQuery = q.Encode()
api, err = apicall("GET", apiURL.String(), *p, nil, false)
if err != nil {
return ipList, api, fmt.Errorf("get iplist - %s", err)
}
json.Unmarshal([]byte(api.RespBody), &ipLists)
// Look for our match and return the first one
for _, ipl := range ipLists {
if ipl.Name == name {
return ipl, api, nil
}
}
// If there is no match we are going to return an empty IP List
return ipList, api, err
}
// getAllIPLists is an internal function to get all IP Lists
// of a specific provision status.
//
// The provision status must be "draft" or "active".
// The first call does not use the async option.
// If the response array length is >=500, it is re-run enabling async.
func (p *PCE) getAllIPLists(provisionStatus string) ([]IPList, APIResponse, error) {
provisionStatus = strings.ToLower(provisionStatus)
if provisionStatus != "active" && provisionStatus != "draft" {
return nil, APIResponse{}, errors.New("get all iplists - provisionStatus must be active or draft")
}
// Build the API URL
apiURL, err := url.Parse("https://" + pceSanitization(p.FQDN) + ":" + strconv.Itoa(p.Port) + "/api/v2/orgs/" + strconv.Itoa(p.Org) + "/sec_policy/" + provisionStatus + "/ip_lists")
if err != nil {
return nil, APIResponse{}, fmt.Errorf("get all iplists - %s", err)
}
// Call the API
api, err := apicall("GET", apiURL.String(), *p, nil, false)
if err != nil {
return nil, api, fmt.Errorf("get all iplists - %s", err)
}
var ipLists []IPList
json.Unmarshal([]byte(api.RespBody), &ipLists)
// If length is 500, re-run with async
if len(ipLists) >= 500 {
api, err = apicall("GET", apiURL.String(), *p, nil, true)
if err != nil {
return nil, api, fmt.Errorf("get all iplists - %s", err)
}
// Unmarshal response to struct
var asyncIPLists []IPList
json.Unmarshal([]byte(api.RespBody), &asyncIPLists)
return asyncIPLists, api, nil
}
// Return if less than 500
return ipLists, api, nil
}
// GetAllIPLists returns a slice of all IPLists in the PCE.
// The function combines the query to get draft and active IP Lists.
// If there are more than 500 of either, async queries will run.
// The []APIResponse will have two entries - first is for draft, second for active.
// The HREF will indicate if it's active or draft.
func (p *PCE) GetAllIPLists() ([]IPList, []APIResponse, error) {
var allIPLists []IPList
draftIPLists, a1, err := p.getAllIPLists("draft")
if err != nil {
return nil, nil, fmt.Errorf("get all iplists - draft - %s", err)
}
activeIPLists, a2, err := p.getAllIPLists("active")
if err != nil {
return nil, nil, fmt.Errorf("get all iplists - active - %s", err)
}
allIPLists = append(append(allIPLists, draftIPLists...), activeIPLists...)
return allIPLists, []APIResponse{a1, a2}, nil
}
// GetAllDraftIPLists returns a slice of draft IPLists
// If there are more than 500 IP Lists, async will run.
func (p *PCE) GetAllDraftIPLists() ([]IPList, APIResponse, error) {
i, a, err := p.getAllIPLists("draft")
if err != nil {
return nil, a, fmt.Errorf("get all draft iplists - %s", err)
}
return i, a, nil
}
// GetAllActiveIPLists returns a slice of draft IPLists
// If there are more than 500 IP Lists, async will run.
func (p *PCE) GetAllActiveIPLists() ([]IPList, APIResponse, error) {
i, a, err := p.getAllIPLists("active")
if err != nil {
return nil, a, fmt.Errorf("get all active iplists - %s", err)
}
return i, a, nil
}
// CreateIPList creates a new IP List in the Illumio PCE.
//
// The function will not remove properties not in the POST schema (e.g., CreatedAt)
func (p *PCE) CreateIPList(ipList IPList) (IPList, APIResponse, error) {
var newIPList IPList
var api APIResponse
var err error
// Build the API URL
apiURL, err := url.Parse("https://" + pceSanitization(p.FQDN) + ":" + strconv.Itoa(p.Port) + "/api/v2/orgs/" + strconv.Itoa(p.Org) + "/sec_policy/draft/ip_lists")
if err != nil {
return newIPList, api, fmt.Errorf("create iplist - %s", err)
}
// Call the API
ipListJSON, err := json.Marshal(ipList)
api.ReqBody = string(ipListJSON)
if err != nil {
return newIPList, api, fmt.Errorf("create iplist - %s", err)
}
api, err = apicall("POST", apiURL.String(), *p, ipListJSON, false)
if err != nil {
return newIPList, api, fmt.Errorf("create iplist - %s", err)
}
// Unmarshal response to struct
json.Unmarshal([]byte(api.RespBody), &newIPList)
return newIPList, api, nil
}
// UpdateIPList updates an existing IP List in the Illumio PCE.
//
// The provided IPList struct must include an Href.
// The function will remove properties not included in the PUT schema.
func (p *PCE) UpdateIPList(iplist IPList) (APIResponse, error) {
var api APIResponse
var err error
// Build the API URL
apiURL, err := url.Parse("https://" + pceSanitization(p.FQDN) + ":" + strconv.Itoa(p.Port) + "/api/v2" + iplist.Href)
if err != nil {
return api, fmt.Errorf("update iplist - %s", err)
}
// Remove fields that should be empty for the PUT schema
iplist.CreatedAt = ""
iplist.CreatedBy = nil
iplist.DeletedAt = ""
iplist.DeletedBy = nil
iplist.Href = ""
iplist.UpdatedAt = ""
iplist.UpdatedBy = nil
// Marshal JSON
ipListJSON, err := json.Marshal(iplist)
if err != nil {
return api, fmt.Errorf("update iplist - %s", err)
}
api.ReqBody = string(ipListJSON)
// Call the API
api, err = apicall("PUT", apiURL.String(), *p, ipListJSON, false)
if err != nil {
return api, fmt.Errorf("update iplist - %s", err)
}
return api, nil
}