Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/m foundation central imaging #422

Merged
merged 14 commits into from
Apr 14, 2022
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
## 1.5.0-beta.2 (April 12, 2022)

[Full Changelog](https://github.com/nutanix/terraform-provider-nutanix/compare/v1.5.0-beta...v1.5.0-beta.2)

**New Feature:**

- Add resources and data sources for Nutanix Foundation Central [\#422](https://github.com/nutanix/terraform-provider-nutanix/pull/422)

New Data Sources :
- nutanix_foundation_central_api_keys
- nutanix_foundation_central_list_api_keys
- nutanix_foundation_central_imaged_nodes_list
- nutanix_foundation_central_imaged_clusters_list
- nutanix_foundation_central_cluster_details
- nutanix_foundation_central_imaged_node_details


New Resources :
- nutanix_foundation_central_image_cluster
- nutanix_foundation_central_api_keys

New Modules :
- aos-based-node-imaging/node-serials-filter
- manual-mode-imaging


## 1.5.0-beta (April 1, 2022)

[Full Changelog](https://github.com/nutanix/terraform-provider-nutanix/compare/v1.4.1...v1.5.0-beta)
Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Terraform provider plugin to integrate with Nutanix Enterprise Cloud

NOTE: The latest version of the Nutanix provider is [v1.5.0-beta](https://github.com/nutanix/terraform-provider-nutanix/releases/tag/v1.5.0-beta)
NOTE: The latest version of the Nutanix provider is [v1.5.0-beta.2](https://github.com/nutanix/terraform-provider-nutanix/releases/tag/v1.5.0-beta.2)

Modules based on Terraform Nutanix Provider can be found here : [Modules](https://github.com/nutanix/terraform-provider-nutanix/tree/master/modules)
## Build, Quality Status
Expand Down Expand Up @@ -47,6 +47,15 @@ Foundation based modules & examples : https://github.com/nutanix/terraform-provi

**Note : Foundation feature in nutanix terraform provider is in beta mode**

## Foundation Central
> For the 1.5.50-beta.2 release of the provider it will have N-1 compatibility with the Foundation Central. This release was tested with v1.2 and v1.3 Foundation Central versions.

Foundation Central based examples : https://github.com/nutanix/terraform-provider-nutanix/blob/master/examples/foundationCentral/

Foundation Central based modules and examples : Foundation based modules & examples : https://github.com/nutanix/terraform-provider-nutanix/blob/master/modules/foundationCentral/

**Note : Foundation Central feature in nutanix terraform provider is in beta mode**

## Example Usage

See the Examples folder for a handful of main.tf demos as well as some pre-compiled binaries.
Expand Down Expand Up @@ -129,6 +138,8 @@ From foundation getting released in 1.5.0-beta, provider configuration will acco
* nutanix_foundation_image_nodes
* nutanix_foundation_ipmi_config
* nutanix_foundation_image
* nutanix_foundation_central_api_keys
* nutanix_foundation_central_image_cluster

## Data Sources

Expand Down Expand Up @@ -170,6 +181,12 @@ From foundation getting released in 1.5.0-beta, provider configuration will acco
* nutanix_foundation_node_network_details
* nutanix_foundation_nos_packages
* nutanix_foundation_hypervisor_isos
* nutanix_foundation_central_api_keys
* nutanix_foundation_central_list_api_keys
* nutanix_foundation_central_imaged_nodes_list
* nutanix_foundation_central_imaged_clusters_list
* nutanix_foundation_central_cluster_details
* nutanix_foundation_central_imaged_node_details

## Quick Install

Expand Down
1 change: 0 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@ func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) error

req = req.WithContext(ctx)
resp, err := c.client.Do(req)

if err != nil {
return err
}
Expand Down
48 changes: 48 additions & 0 deletions client/fc/fc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package foundationcentral

import (
"fmt"
"strings"

"github.com/terraform-providers/terraform-provider-nutanix/client"
)

const (
libraryVersion = "v1"
absolutePath = "api/fc/" + libraryVersion
userAgent = "nutanix/" + libraryVersion
clientName = "foundation_central"
)

// Client manages the foundation central API
type Client struct {
client *client.Client
Service Service
}

// NewFoundationCentralClient return a client to operate foundation central resources
func NewFoundationCentralClient(credentials client.Credentials) (*Client, error) {
var baseClient *client.Client

// check if all required fields are present. Else create an empty client
if credentials.Username != "" && credentials.Password != "" && credentials.Endpoint != "" {
c, err := client.NewClient(&credentials, userAgent, absolutePath, false)
if err != nil {
return nil, err
}
baseClient = c
} else {
errorMsg := fmt.Sprintf("Foundation Central Client is missing. "+
"Please provide required details - %s in provider configuration.", strings.Join(credentials.RequiredFields[clientName], ", "))

baseClient = &client.Client{UserAgent: userAgent, ErrorMsg: errorMsg}
}

fc := &Client{
client: baseClient,
Service: Operations{
client: baseClient,
},
}
return fc, nil
}
216 changes: 216 additions & 0 deletions client/fc/fc_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package foundationcentral

import (
"context"
"fmt"
"net/http"

"github.com/terraform-providers/terraform-provider-nutanix/client"
)

// Operations implements Service interface
type Operations struct {
client *client.Client
}

// Interface for foundation central apis
type Service interface {
GetImagedNode(context.Context, string) (*ImagedNodeDetails, error)
ListImagedNodes(context.Context, *ImagedNodesListInput) (*ImagedNodesListResponse, error)
GetImagedCluster(context.Context, string) (*ImagedClusterDetails, error)
ListImagedClusters(context.Context, *ImagedClustersListInput) (*ImagedClustersListResponse, error)
CreateCluster(context.Context, *CreateClusterInput) (*CreateClusterResponse, error)
UpdateCluster(context.Context, string, *UpdateClusterData) error
DeleteCluster(context.Context, string) error
CreateAPIKey(context.Context, *CreateAPIKeysInput) (*CreateAPIKeysResponse, error)
GetAPIKey(context.Context, string) (*CreateAPIKeysResponse, error)
ListAPIKeys(context.Context, *ListMetadataInput) (*ListAPIKeysResponse, error)
}

/*GetImagedNode Get the details of an imaged node
* This operation fetches the node details of a node given it's node uuid
*
* @param nodeUUID The uuid of the node.
* @return *ImagedNodeDetails
*/
func (op Operations) GetImagedNode(ctx context.Context, nodeUUID string) (*ImagedNodeDetails, error) {
path := fmt.Sprintf("/imaged_nodes/%s", nodeUUID)

req, err := op.client.NewRequest(ctx, http.MethodGet, path, nil)
imagedNodeDetails := new(ImagedNodeDetails)

if err != nil {
return nil, err
}

return imagedNodeDetails, op.client.Do(ctx, req, imagedNodeDetails)
}

/*ListImagedNodes Get all the imaged node within FC
* This operation fetches all the imaged nodes within FC
*
* @param input
* @return *ImagedNodesListResponse
*/
func (op Operations) ListImagedNodes(ctx context.Context, input *ImagedNodesListInput) (*ImagedNodesListResponse, error) {
path := "/imaged_nodes/list"

req, err := op.client.NewRequest(ctx, http.MethodPost, path, input)

imagedNodesListResponse := new(ImagedNodesListResponse)

if err != nil {
return nil, err
}

return imagedNodesListResponse, op.client.Do(ctx, req, imagedNodesListResponse)
}

/*GetImagedCluster Get the details of an imaged cluster
* This operation fetches the details of a cluster given it's uuid
*
* @param clusterUUID uuid of the imaged cluster
* @return *ImagedClusterDetails
*/
func (op Operations) GetImagedCluster(ctx context.Context, clusterUUID string) (*ImagedClusterDetails, error) {
path := fmt.Sprintf("/imaged_clusters/%s", clusterUUID)

req, err := op.client.NewRequest(ctx, http.MethodGet, path, nil)
imagedClusterDetails := new(ImagedClusterDetails)

if err != nil {
return nil, err
}

return imagedClusterDetails, op.client.Do(ctx, req, imagedClusterDetails)
}

/*ListImagedNodes Get all the imaged clusters within FC
* This operation fetches all the imaged clusters within FC
*
* @param input
* @return *ImagedClustersListResponse
*/
func (op Operations) ListImagedClusters(ctx context.Context, input *ImagedClustersListInput) (*ImagedClustersListResponse, error) {
path := "/imaged_clusters/list"

req, err := op.client.NewRequest(ctx, http.MethodPost, path, input)

imagedClustersListResponse := new(ImagedClustersListResponse)

if err != nil {
return nil, err
}

return imagedClustersListResponse, op.client.Do(ctx, req, imagedClustersListResponse)
}

/*CreateCluster Creates a Cluster
* This operation submits a request to create a cluster or image nodes based on the input parameters.
*
* @param input
* @return *CreateClusterResponse
*/
func (op Operations) CreateCluster(ctx context.Context, input *CreateClusterInput) (*CreateClusterResponse, error) {
path := "/imaged_clusters"

req, err := op.client.NewRequest(ctx, http.MethodPost, path, input)

createClusterResponse := new(CreateClusterResponse)

if err != nil {
return nil, err
}

return createClusterResponse, op.client.Do(ctx, req, createClusterResponse)
}

/*UpdateCluster Updates a Cluster
* This operation submits a request to archieve the cluster.
*
* @param clusterUUID
* @return *UpdateClusterData
*/
func (op Operations) UpdateCluster(ctx context.Context, clusterUUID string, updateData *UpdateClusterData) error {
path := fmt.Sprintf("/imaged_clusters/%s", clusterUUID)

req, err := op.client.NewRequest(ctx, http.MethodPut, path, updateData)

if err != nil {
return err
}

return op.client.Do(ctx, req, nil)
}

/*DeleteCluster Deletes Cluster
* This operation submits a request to delete the cluster on Foundation central
*
* @param clusterUUID
* @return error
*/
func (op Operations) DeleteCluster(ctx context.Context, clusterUUID string) error {
path := fmt.Sprintf("/imaged_clusters/%s", clusterUUID)

req, err := op.client.NewRequest(ctx, http.MethodDelete, path, nil)

if err != nil {
return err
}

return op.client.Do(ctx, req, nil)
}

/*CreateAPIKey Creates a new API Key
* This Operation creates a new api key which will be used by remote nodes to authenticate with Foundation Central
*
* @param input
* @return CreateAPIKeysResponse
*/
func (op Operations) CreateAPIKey(ctx context.Context, input *CreateAPIKeysInput) (*CreateAPIKeysResponse, error) {
path := "/api_keys"

req, err := op.client.NewRequest(ctx, http.MethodPost, path, input)
if err != nil {
return nil, err
}

createAPIResponse := new(CreateAPIKeysResponse)
return createAPIResponse, op.client.Do(ctx, req, createAPIResponse)
}

/*GetAPIKey Gets the details of an API key
* Get an api key given its UUID.
* @param uuid The uuid of an API Key
* @return CreateAPIKeysResponse
*/

func (op Operations) GetAPIKey(ctx context.Context, uuid string) (*CreateAPIKeysResponse, error) {
path := fmt.Sprintf("/api_keys/%s", uuid)

req, err := op.client.NewRequest(ctx, http.MethodGet, path, uuid)
if err != nil {
return nil, err
}

getAPIResponse := new(CreateAPIKeysResponse)
return getAPIResponse, op.client.Do(ctx, req, getAPIResponse)
}

/*ListAPIKeys Gets all the API Keys within Foundation Central
* List all the api keys.
* @param body
* @return ListAPIKeysResponse
*/

func (op Operations) ListAPIKeys(ctx context.Context, body *ListMetadataInput) (*ListAPIKeysResponse, error) {
path := "/api_keys/list"

req, err := op.client.NewRequest(ctx, http.MethodPost, path, body)
if err != nil {
return nil, err
}

listAPIKeysResponse := new(ListAPIKeysResponse)
return listAPIKeysResponse, op.client.Do(ctx, req, listAPIKeysResponse)
}
Loading