Skip to content

Commit

Permalink
Subscriptions Vendor Passthru support (#2201)
Browse files Browse the repository at this point in the history
This commit adds support for the following vendor passthru methods:
- create_subscription
- delete_subscription
- get_subscription
- get_all_subscriptions

This methods are only supported by redfish implementations in ironic
that are using the vendor passthru.
  • Loading branch information
iurygregory authored Aug 10, 2021
1 parent 1e1b375 commit ad8066c
Show file tree
Hide file tree
Showing 6 changed files with 652 additions and 0 deletions.
62 changes: 62 additions & 0 deletions openstack/baremetal/v1/nodes/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,67 @@ Example to get boot device for a node
if err != nil {
panic(err)
}
Example to list all vendor passthru methods
methods, err := nodes.GetVendorPassthruMethods(client, "a62b8495-52e2-407b-b3cb-62775d04c2b8").Extract()
if err != nil {
panic(err)
}
Example to list all subscriptions
method := nodes.CallVendorPassthruOpts{
Method: "get_all_subscriptions",
}
allSubscriptions, err := nodes.GetAllSubscriptions(client, "a62b8495-52e2-407b-b3cb-62775d04c2b8", method).Extract()
if err != nil {
panic(err)
}
Example to get a subscription
method := nodes.CallVendorPassthruOpts{
Method: "get_subscription",
}
subscriptionOpt := nodes.GetSubscriptionOpts{
Id: "subscription id",
}
subscription, err := nodes.GetSubscription(client, "a62b8495-52e2-407b-b3cb-62775d04c2b8", method, subscriptionOpt).Extract()
if err != nil {
panic(err)
}
Example to delete a subscription
method := nodes.CallVendorPassthruOpts{
Method: "delete_subscription",
}
subscriptionDeleteOpt := nodes.DeleteSubscriptionOpts{
Id: "subscription id",
}
err := nodes.DeleteSubscription(client, "a62b8495-52e2-407b-b3cb-62775d04c2b8", method, subscriptionDeleteOpt).ExtractErr()
if err != nil {
panic(err)
}
Example to create a subscription
method := nodes.CallVendorPassthruOpts{
Method: "create_subscription",
}
subscriptionCreateOpt := nodes.CreateSubscriptionOpts{
Destination: "https://subscription_destination_url"
Context: "MyContext",
Protocol: "Redfish",
EventTypes: ["Alert"],
}
newSubscription, err := nodes.CreateSubscription(client, "a62b8495-52e2-407b-b3cb-62775d04c2b8", method, subscriptionCreateOpt).Extract()
if err != nil {
panic(err)
}
*/
package nodes
140 changes: 140 additions & 0 deletions openstack/baremetal/v1/nodes/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,3 +694,143 @@ func GetBIOSSetting(client *gophercloud.ServiceClient, id string, setting string
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// CallVendorPassthruOpts defines query options that can be passed to any VendorPassthruCall
type CallVendorPassthruOpts struct {
Method string `q:"method"`
}

// ToGetSubscriptionMap assembles a query based on the contents of a CallVendorPassthruOpts
func ToGetAllSubscriptionMap(opts CallVendorPassthruOpts) (string, error) {
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
}

// Get all vendor_passthru methods available for the given Node.
func GetVendorPassthruMethods(client *gophercloud.ServiceClient, id string) (r VendorPassthruMethodsResult) {
resp, err := client.Get(vendorPassthruMethodsURL(client, id), &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// Get all subscriptions available for the given Node.
func GetAllSubscriptions(client *gophercloud.ServiceClient, id string, method CallVendorPassthruOpts) (r GetAllSubscriptionsVendorPassthruResult) {
query, err := ToGetAllSubscriptionMap(method)
if err != nil {
r.Err = err
return
}
url := vendorPassthruCallURL(client, id) + query
resp, err := client.Get(url, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// The desired subscription id on the baremetal node.
type GetSubscriptionOpts struct {
Id string `json:"id"`
}

// ToGetSubscriptionMap assembles a query based on the contents of CallVendorPassthruOpts and a request body based on the contents of a GetSubscriptionOpts
func ToGetSubscriptionMap(method CallVendorPassthruOpts, opts GetSubscriptionOpts) (string, map[string]interface{}, error) {
q, err := gophercloud.BuildQueryString(method)
if err != nil {
return q.String(), nil, err
}
body, err := gophercloud.BuildRequestBody(opts, "")
if err != nil {
return q.String(), nil, err
}

return q.String(), body, nil
}

// Get a subscription on the given Node.
func GetSubscription(client *gophercloud.ServiceClient, id string, method CallVendorPassthruOpts, subscriptionOpts GetSubscriptionOpts) (r SubscriptionVendorPassthruResult) {
query, reqBody, err := ToGetSubscriptionMap(method, subscriptionOpts)
if err != nil {
r.Err = err
return
}
url := vendorPassthruCallURL(client, id) + query
resp, err := client.Get(url, &r.Body, &gophercloud.RequestOpts{
JSONBody: reqBody,
OkCodes: []int{200},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// The desired subscription to be deleted from the baremetal node.
type DeleteSubscriptionOpts struct {
Id string `json:"id"`
}

// ToDeleteSubscriptionMap assembles a query based on the contents of CallVendorPassthruOpts and a request body based on the contents of a DeleteSubscriptionOpts
func ToDeleteSubscriptionMap(method CallVendorPassthruOpts, opts DeleteSubscriptionOpts) (string, map[string]interface{}, error) {
q, err := gophercloud.BuildQueryString(method)
if err != nil {
return q.String(), nil, err
}
body, err := gophercloud.BuildRequestBody(opts, "")
if err != nil {
return q.String(), nil, err
}
return q.String(), body, nil
}

// Delete a subscription on the given node.
func DeleteSubscription(client *gophercloud.ServiceClient, id string, method CallVendorPassthruOpts, subscriptionOpts DeleteSubscriptionOpts) (r DeleteSubscriptionVendorPassthruResult) {
query, reqBody, err := ToDeleteSubscriptionMap(method, subscriptionOpts)
if err != nil {
r.Err = err
return
}
url := vendorPassthruCallURL(client, id) + query
resp, err := client.Delete(url, &gophercloud.RequestOpts{
JSONBody: reqBody,
OkCodes: []int{200, 202, 204},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return r
}

// The desired subscription to be created from the baremetal node.
type CreateSubscriptionOpts struct {
Destination string `json:"Destination"`
EventTypes []string `json:"EventTypes,omitempty"`
Context string `json:"Context,omitempty"`
Protocol string `json:"Protocol,omitempty"`
}

// ToCreateSubscriptionMap assembles a query based on the contents of CallVendorPassthruOpts and a request body based on the contents of a CreateSubscriptionOpts
func ToCreateSubscriptionMap(method CallVendorPassthruOpts, opts CreateSubscriptionOpts) (string, map[string]interface{}, error) {
q, err := gophercloud.BuildQueryString(method)
if err != nil {
return q.String(), nil, err
}
body, err := gophercloud.BuildRequestBody(opts, "")
if err != nil {
return q.String(), nil, err
}
return q.String(), body, nil
}

// Creates a subscription on the given node.
func CreateSubscription(client *gophercloud.ServiceClient, id string, method CallVendorPassthruOpts, subscriptionOpts CreateSubscriptionOpts) (r SubscriptionVendorPassthruResult) {
query, reqBody, err := ToCreateSubscriptionMap(method, subscriptionOpts)
if err != nil {
r.Err = err
return
}
url := vendorPassthruCallURL(client, id) + query
resp, err := client.Post(url, reqBody, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return r
}
105 changes: 105 additions & 0 deletions openstack/baremetal/v1/nodes/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,25 @@ func (r GetBIOSSettingResult) Extract() (*BIOSSetting, error) {
return &s.Setting, err
}

// Extract interprets a VendorPassthruMethod as
func (r VendorPassthruMethodsResult) Extract() (*VendorPassthruMethods, error) {
var s VendorPassthruMethods
err := r.ExtractInto(&s)
return &s, err
}

func (r GetAllSubscriptionsVendorPassthruResult) Extract() (*GetAllSubscriptionsVendorPassthru, error) {
var s GetAllSubscriptionsVendorPassthru
err := r.ExtractInto(&s)
return &s, err
}

func (r SubscriptionVendorPassthruResult) Extract() (*SubscriptionVendorPassthru, error) {
var s SubscriptionVendorPassthru
err := r.ExtractInto(&s)
return &s, err
}

// Node represents a node in the OpenStack Bare Metal API.
type Node struct {
// Whether automated cleaning is enabled or disabled on this node.
Expand Down Expand Up @@ -323,6 +342,30 @@ type GetBIOSSettingResult struct {
gophercloud.Result
}

// VendorPassthruMethodsResult is the response from a GetVendorPassthruMethods operation. Call its Extract
// method to interpret it as an array of allowed vendor methods.
type VendorPassthruMethodsResult struct {
gophercloud.Result
}

// GetAllSubscriptionsVendorPassthruResult is the response from GetAllSubscriptions operation. Call its
// Extract method to interpret it as a GetAllSubscriptionsVendorPassthru struct.
type GetAllSubscriptionsVendorPassthruResult struct {
gophercloud.Result
}

// SubscriptionVendorPassthruResult is the response from GetSubscription and CreateSubscription operation. Call its Extract
// method to interpret it as a SubscriptionVendorPassthru struct.
type SubscriptionVendorPassthruResult struct {
gophercloud.Result
}

// DeleteSubscriptionVendorPassthruResult is the response from DeleteSubscription operation. Call its
// ExtractErr method to determine if the call succeeded of failed.
type DeleteSubscriptionVendorPassthruResult struct {
gophercloud.ErrResult
}

// Each element in the response will contain a “result” variable, which will have a value of “true” or “false”, and
// also potentially a reason. A value of nil indicates that the Node’s driver does not support that interface.
type DriverValidation struct {
Expand Down Expand Up @@ -396,3 +439,65 @@ type SingleBIOSSetting struct {
type ChangeStateResult struct {
gophercloud.ErrResult
}

type VendorPassthruMethods struct {
CreateSubscription CreateSubscriptionMethod `json:"create_subscription,omitempty"`
DeleteSubscription DeleteSubscriptionMethod `json:"delete_subscription,omitempty"`
GetSubscription GetSubscriptionMethod `json:"get_subscription,omitempty"`
GetAllSubscriptions GetAllSubscriptionsMethod `json:"get_all_subscriptions,omitempty"`
}

// Below you can find all vendor passthru methods structs

type CreateSubscriptionMethod struct {
HTTPMethods []string `json:"http_methods"`
Async bool `json:"async"`
Description string `json:"description"`
Attach bool `json:"attach"`
RequireExclusiveLock bool `json:"require_exclusive_lock"`
}

type DeleteSubscriptionMethod struct {
HTTPMethods []string `json:"http_methods"`
Async bool `json:"async"`
Description string `json:"description"`
Attach bool `json:"attach"`
RequireExclusiveLock bool `json:"require_exclusive_lock"`
}

type GetSubscriptionMethod struct {
HTTPMethods []string `json:"http_methods"`
Async bool `json:"async"`
Description string `json:"description"`
Attach bool `json:"attach"`
RequireExclusiveLock bool `json:"require_exclusive_lock"`
}

type GetAllSubscriptionsMethod struct {
HTTPMethods []string `json:"http_methods"`
Async bool `json:"async"`
Description string `json:"description"`
Attach bool `json:"attach"`
RequireExclusiveLock bool `json:"require_exclusive_lock"`
}

// A List of subscriptions from a node in the OpenStack Bare Metal API.
type GetAllSubscriptionsVendorPassthru struct {
Context string `json:"@odata.context"`
Etag string `json:"@odata.etag"`
Id string `json:"@odata.id"`
Type string `json:"@odata.type"`
Description string `json:"Description"`
Name string `json:"Name"`
Members []map[string]string `json:"Members"`
MembersCount int `json:"Members@odata.count"`
}

// A Subscription from a node in the OpenStack Bare Metal API.
type SubscriptionVendorPassthru struct {
Id string `json:"Id"`
Context string `json:"Context"`
Destination string `json:"Destination"`
EventTypes []string `json:"EventTypes"`
Protocol string `json:"Protocol"`
}
Loading

0 comments on commit ad8066c

Please sign in to comment.