Skip to content

Commit 3faeebe

Browse files
committed
Add support for SSL-offload profiles.
DimensionDataResearch/terraform-provider-ddcloud#104
1 parent c8874b6 commit 3faeebe

File tree

3 files changed

+252
-0
lines changed

3 files changed

+252
-0
lines changed

compute/resources.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ const (
5353

5454
// ResourceTypeSSLCertificateChain represents an SSL certificate chain
5555
ResourceTypeSSLCertificateChain
56+
57+
// ResourceTypeSSLOffloadProfile represents an SSL-offload profile
58+
ResourceTypeSSLOffloadProfile
5659
)
5760

5861
// Resource represents a compute resource.
@@ -114,6 +117,9 @@ func GetResourceDescription(resourceType ResourceType) (string, error) {
114117
case ResourceTypeSSLCertificateChain:
115118
return "SSL certificate chain", nil
116119

120+
case ResourceTypeSSLOffloadProfile:
121+
return "SSL-offload profile", nil
122+
117123
default:
118124
return "", fmt.Errorf("unrecognised resource type (value = %d)", resourceType)
119125
}
@@ -165,6 +171,9 @@ func (client *Client) GetResource(id string, resourceType ResourceType) (Resourc
165171

166172
case ResourceTypeSSLCertificateChain:
167173
return client.GetSSLCertificateChain(id)
174+
175+
case ResourceTypeSSLOffloadProfile:
176+
return client.GetSSLOffloadProfile(id)
168177
}
169178

170179
return nil, fmt.Errorf("unrecognised resource type (value = %d)", resourceType)

compute/ssl_offload_profiles.go

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
package compute
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
)
9+
10+
// SSLOffloadProfile represents an SSL-offload profile.
11+
type SSLOffloadProfile struct {
12+
ID string `json:"id"`
13+
Name string `json:"name"`
14+
Description string `json:"description"`
15+
SSLDomainCertificate EntityReference `json:"sslDomainCertificate"`
16+
SSLCertificateChain EntityReference `json:"sslCertificateChain"`
17+
Ciphers string `json:"ciphers"`
18+
State string `json:"state"`
19+
DatacenterID string `json:"datacenterId"`
20+
NetworkDomainID string `json:"networkDomainId"`
21+
}
22+
23+
// GetID returns the offload profile's Id.
24+
func (offloadProfile *SSLOffloadProfile) GetID() string {
25+
return offloadProfile.ID
26+
}
27+
28+
// GetResourceType returns the offload profile's resource type.
29+
func (offloadProfile *SSLOffloadProfile) GetResourceType() ResourceType {
30+
return ResourceTypeSSLOffloadProfile
31+
}
32+
33+
// GetName returns the offload profile's name.
34+
func (offloadProfile *SSLOffloadProfile) GetName() string {
35+
return offloadProfile.Name
36+
}
37+
38+
// GetState returns the offload profile's current state.
39+
func (offloadProfile *SSLOffloadProfile) GetState() string {
40+
return offloadProfile.State
41+
}
42+
43+
// IsDeleted determines whether the offload profile has been deleted (is nil).
44+
func (offloadProfile *SSLOffloadProfile) IsDeleted() bool {
45+
return offloadProfile == nil
46+
}
47+
48+
var _ Resource = &SSLOffloadProfile{}
49+
50+
// ToEntityReference creates an EntityReference representing the offload profile.
51+
func (offloadProfile *SSLOffloadProfile) ToEntityReference() EntityReference {
52+
return EntityReference{
53+
ID: offloadProfile.ID,
54+
Name: offloadProfile.Name,
55+
}
56+
}
57+
58+
var _ NamedEntity = &SSLOffloadProfile{}
59+
60+
// SSLOffloadProfiles represents a page of SSLOffloadProfile results.
61+
type SSLOffloadProfiles struct {
62+
Items []SSLOffloadProfile `json:"sslOffloadProfile"`
63+
64+
PagedResult
65+
}
66+
67+
// Request body when createing an SSL-offload profile.
68+
type createSSLOffloadProfile struct {
69+
Name string `json:"name"`
70+
Description string `json:"description"`
71+
Ciphers string `json:"ciphers"`
72+
SSLDomainCertificateID string `json:"sslDomainCertificateId"`
73+
SSLCertificateChainID string `json:"sslCertificateChainId,omitempty"`
74+
NetworkDomainID string `json:"networkDomainId"`
75+
}
76+
77+
// Request body when deleting an SSL-offload profile.
78+
type deleteSSLOffloadProfile struct {
79+
// The SSL-offload profile Id.
80+
ID string `json:"id"`
81+
}
82+
83+
// ListSSLOffloadProfilesInNetworkDomain retrieves a list of all SSL-offload profiles in the specified network domain.
84+
func (client *Client) ListSSLOffloadProfilesInNetworkDomain(networkDomainID string, paging *Paging) (pools *SSLOffloadProfiles, err error) {
85+
organizationID, err := client.getOrganizationID()
86+
if err != nil {
87+
return nil, err
88+
}
89+
90+
requestURI := fmt.Sprintf("%s/networkDomainVip/sslOffloadProfile?networkDomainId=%s&%s",
91+
url.QueryEscape(organizationID),
92+
url.QueryEscape(networkDomainID),
93+
paging.EnsurePaging().toQueryParameters(),
94+
)
95+
request, err := client.newRequestV26(requestURI, http.MethodGet, nil)
96+
if err != nil {
97+
return nil, err
98+
}
99+
100+
responseBody, statusCode, err := client.executeRequest(request)
101+
if err != nil {
102+
return nil, err
103+
}
104+
105+
if statusCode != http.StatusOK {
106+
var apiResponse *APIResponseV2
107+
108+
apiResponse, err = readAPIResponseAsJSON(responseBody, statusCode)
109+
if err != nil {
110+
return nil, err
111+
}
112+
113+
return nil, apiResponse.ToError("Request to list SSL-offload profiles in network domain '%s' failed with status code %d (%s): %s", networkDomainID, statusCode, apiResponse.ResponseCode, apiResponse.Message)
114+
}
115+
116+
pools = &SSLOffloadProfiles{}
117+
err = json.Unmarshal(responseBody, pools)
118+
if err != nil {
119+
return nil, err
120+
}
121+
122+
return pools, nil
123+
}
124+
125+
// GetSSLOffloadProfile retrieves the SSL-offload profile with the specified Id.
126+
//
127+
// Returns nil if no SSL-offload profile is found with the specified Id.
128+
func (client *Client) GetSSLOffloadProfile(id string) (pool *SSLOffloadProfile, err error) {
129+
organizationID, err := client.getOrganizationID()
130+
if err != nil {
131+
return nil, err
132+
}
133+
134+
requestURI := fmt.Sprintf("%s/networkDomainVip/sslOffloadProfile/%s",
135+
url.QueryEscape(organizationID),
136+
url.QueryEscape(id),
137+
)
138+
request, err := client.newRequestV26(requestURI, http.MethodGet, nil)
139+
if err != nil {
140+
return nil, err
141+
}
142+
responseBody, statusCode, err := client.executeRequest(request)
143+
if err != nil {
144+
return nil, err
145+
}
146+
147+
if statusCode != http.StatusOK {
148+
var apiResponse *APIResponseV2
149+
150+
apiResponse, err = readAPIResponseAsJSON(responseBody, statusCode)
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
if apiResponse.ResponseCode == ResponseCodeResourceNotFound {
156+
return nil, nil // Not an error, but was not found.
157+
}
158+
159+
return nil, apiResponse.ToError("Request to retrieve SSL-offload profile with Id '%s' failed with status code %d (%s): %s", id, statusCode, apiResponse.ResponseCode, apiResponse.Message)
160+
}
161+
162+
pool = &SSLOffloadProfile{}
163+
err = json.Unmarshal(responseBody, pool)
164+
if err != nil {
165+
return nil, err
166+
}
167+
168+
return pool, nil
169+
}
170+
171+
// CreateSSLOffloadProfile creates an SSL-offload profile in a network domain.
172+
func (client *Client) CreateSSLOffloadProfile(networkDomainID string, name string, description string, ciphers string, sslDomainCertificateID string, sslCertificateChainID string) (offloadProfileID string, err error) {
173+
organizationID, err := client.getOrganizationID()
174+
if err != nil {
175+
return "", err
176+
}
177+
178+
requestURI := fmt.Sprintf("%s/networkDomainVip/createSslOffloadProfile",
179+
url.QueryEscape(organizationID),
180+
)
181+
request, err := client.newRequestV26(requestURI, http.MethodPost, &createSSLOffloadProfile{
182+
Name: name,
183+
Description: description,
184+
Ciphers: ciphers,
185+
SSLDomainCertificateID: sslDomainCertificateID,
186+
SSLCertificateChainID: sslCertificateChainID,
187+
NetworkDomainID: networkDomainID,
188+
})
189+
responseBody, statusCode, err := client.executeRequest(request)
190+
if err != nil {
191+
return "", err
192+
}
193+
194+
apiResponse, err := readAPIResponseAsJSON(responseBody, statusCode)
195+
if err != nil {
196+
return "", err
197+
}
198+
199+
if apiResponse.ResponseCode != ResponseCodeOK {
200+
return "", apiResponse.ToError("Request to create SSL-offload profile '%s' failed with status code %d (%s): %s", name, statusCode, apiResponse.ResponseCode, apiResponse.Message)
201+
}
202+
203+
// Expected: "info" { "name": "sslOffloadProfileId", "value": "the-Id-of-the-createed-certificate" }
204+
sslOffloadProfileIDMessage := apiResponse.GetFieldMessage("sslOffloadProfileId")
205+
if sslOffloadProfileIDMessage == nil {
206+
return "", apiResponse.ToError("Received an unexpected response (missing 'sslOffloadProfileId') with status code %d (%s): %s", statusCode, apiResponse.ResponseCode, apiResponse.Message)
207+
}
208+
209+
return *sslOffloadProfileIDMessage, nil
210+
}
211+
212+
// DeleteSSLOffloadProfile deletes an existing SSL-offload profile.
213+
//
214+
// Returns an error if the operation was not successful.
215+
func (client *Client) DeleteSSLOffloadProfile(id string) (err error) {
216+
organizationID, err := client.getOrganizationID()
217+
if err != nil {
218+
return err
219+
}
220+
221+
requestURI := fmt.Sprintf("%s/networkDomainVip/deleteSslOffloadProfile",
222+
url.QueryEscape(organizationID),
223+
)
224+
request, err := client.newRequestV26(requestURI, http.MethodPost, &deleteSSLOffloadProfile{id})
225+
responseBody, statusCode, err := client.executeRequest(request)
226+
if err != nil {
227+
return err
228+
}
229+
230+
apiResponse, err := readAPIResponseAsJSON(responseBody, statusCode)
231+
if err != nil {
232+
return err
233+
}
234+
235+
if apiResponse.ResponseCode != ResponseCodeOK {
236+
return apiResponse.ToError("Request to delete SSL-offload profile '%s' failed with unexpected status code %d (%s): %s", id, statusCode, apiResponse.ResponseCode, apiResponse.Message)
237+
}
238+
239+
return nil
240+
}

compute/virtual_listeners.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ type VirtualListener struct {
8181
ClientClonePool VirtualListenerVIPPoolRef `json:"ClientClonePool"`
8282
PersistenceProfile EntityReference `json:"persistenceProfile"`
8383
FallbackPersistenceProfile EntityReference `json:"fallbackPersistenceProfile"`
84+
SSLOffloadProfile EntityReference `json:"sslOffloadProfile"`
8485
OptimizationProfiles []string `json:"optimizationProfile"`
8586
IRules []EntityReference `json:"irule"`
8687
State string `json:"state"`
@@ -156,6 +157,7 @@ type NewVirtualListenerConfiguration struct {
156157
ClientClonePoolID *string `json:"clientClonePoolId,omitempty"`
157158
PersistenceProfileID *string `json:"persistenceProfileId,omitempty"`
158159
FallbackPersistenceProfileID *string `json:"fallbackPersistenceProfileId,omitempty"`
160+
SSLOffloadProfileID *string `json:"sslOffloadProfileId,omitempty"`
159161
IRuleIDs []string `json:"iruleId"`
160162
OptimizationProfiles []string `json:"optimizationProfile"`
161163
NetworkDomainID string `json:"networkDomainId"`
@@ -171,6 +173,7 @@ type EditVirtualListenerConfiguration struct {
171173
SourcePortPreservation *string `json:"sourcePortPreservation,omitempty"`
172174
PoolID *string `json:"poolId,omitempty"`
173175
PersistenceProfileID *string `json:"persistenceProfileId,omitempty"`
176+
SSLOffloadProfileID *string `json:"sslOffloadProfileId,omitempty"`
174177
IRuleIDs *[]string `json:"iruleId,omitempty"`
175178
OptimizationProfiles *[]string `json:"optimizationProfile,omitempty"`
176179
}

0 commit comments

Comments
 (0)