// Code generated by go-swagger; DO NOT EDIT.

// Copyright 2018 The go-netbox Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package virtualization

// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command

import (
	"github.com/go-openapi/runtime"

	strfmt "github.com/go-openapi/strfmt"
)

// New creates a new virtualization API client.
func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client {
	return &Client{transport: transport, formats: formats}
}

/*
Client for virtualization API
*/
type Client struct {
	transport runtime.ClientTransport
	formats   strfmt.Registry
}

/*
VirtualizationChoicesList virtualization choices list API
*/
func (a *Client) VirtualizationChoicesList(params *VirtualizationChoicesListParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationChoicesListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationChoicesListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization__choices_list",
		Method:             "GET",
		PathPattern:        "/virtualization/_choices/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationChoicesListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationChoicesListOK), nil

}

/*
VirtualizationChoicesRead virtualization choices read API
*/
func (a *Client) VirtualizationChoicesRead(params *VirtualizationChoicesReadParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationChoicesReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationChoicesReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization__choices_read",
		Method:             "GET",
		PathPattern:        "/virtualization/_choices/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationChoicesReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationChoicesReadOK), nil

}

/*
VirtualizationClusterGroupsCreate virtualization cluster groups create API
*/
func (a *Client) VirtualizationClusterGroupsCreate(params *VirtualizationClusterGroupsCreateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterGroupsCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterGroupsCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-groups_create",
		Method:             "POST",
		PathPattern:        "/virtualization/cluster-groups/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterGroupsCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterGroupsCreateCreated), nil

}

/*
VirtualizationClusterGroupsDelete virtualization cluster groups delete API
*/
func (a *Client) VirtualizationClusterGroupsDelete(params *VirtualizationClusterGroupsDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterGroupsDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterGroupsDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-groups_delete",
		Method:             "DELETE",
		PathPattern:        "/virtualization/cluster-groups/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterGroupsDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterGroupsDeleteNoContent), nil

}

/*
VirtualizationClusterGroupsList virtualization cluster groups list API
*/
func (a *Client) VirtualizationClusterGroupsList(params *VirtualizationClusterGroupsListParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterGroupsListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterGroupsListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-groups_list",
		Method:             "GET",
		PathPattern:        "/virtualization/cluster-groups/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterGroupsListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterGroupsListOK), nil

}

/*
VirtualizationClusterGroupsPartialUpdate virtualization cluster groups partial update API
*/
func (a *Client) VirtualizationClusterGroupsPartialUpdate(params *VirtualizationClusterGroupsPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterGroupsPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterGroupsPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-groups_partial_update",
		Method:             "PATCH",
		PathPattern:        "/virtualization/cluster-groups/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterGroupsPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterGroupsPartialUpdateOK), nil

}

/*
VirtualizationClusterGroupsRead virtualization cluster groups read API
*/
func (a *Client) VirtualizationClusterGroupsRead(params *VirtualizationClusterGroupsReadParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterGroupsReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterGroupsReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-groups_read",
		Method:             "GET",
		PathPattern:        "/virtualization/cluster-groups/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterGroupsReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterGroupsReadOK), nil

}

/*
VirtualizationClusterGroupsUpdate virtualization cluster groups update API
*/
func (a *Client) VirtualizationClusterGroupsUpdate(params *VirtualizationClusterGroupsUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterGroupsUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterGroupsUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-groups_update",
		Method:             "PUT",
		PathPattern:        "/virtualization/cluster-groups/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterGroupsUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterGroupsUpdateOK), nil

}

/*
VirtualizationClusterTypesCreate virtualization cluster types create API
*/
func (a *Client) VirtualizationClusterTypesCreate(params *VirtualizationClusterTypesCreateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterTypesCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterTypesCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-types_create",
		Method:             "POST",
		PathPattern:        "/virtualization/cluster-types/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterTypesCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterTypesCreateCreated), nil

}

/*
VirtualizationClusterTypesDelete virtualization cluster types delete API
*/
func (a *Client) VirtualizationClusterTypesDelete(params *VirtualizationClusterTypesDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterTypesDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterTypesDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-types_delete",
		Method:             "DELETE",
		PathPattern:        "/virtualization/cluster-types/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterTypesDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterTypesDeleteNoContent), nil

}

/*
VirtualizationClusterTypesList virtualization cluster types list API
*/
func (a *Client) VirtualizationClusterTypesList(params *VirtualizationClusterTypesListParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterTypesListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterTypesListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-types_list",
		Method:             "GET",
		PathPattern:        "/virtualization/cluster-types/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterTypesListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterTypesListOK), nil

}

/*
VirtualizationClusterTypesPartialUpdate virtualization cluster types partial update API
*/
func (a *Client) VirtualizationClusterTypesPartialUpdate(params *VirtualizationClusterTypesPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterTypesPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterTypesPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-types_partial_update",
		Method:             "PATCH",
		PathPattern:        "/virtualization/cluster-types/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterTypesPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterTypesPartialUpdateOK), nil

}

/*
VirtualizationClusterTypesRead virtualization cluster types read API
*/
func (a *Client) VirtualizationClusterTypesRead(params *VirtualizationClusterTypesReadParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterTypesReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterTypesReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-types_read",
		Method:             "GET",
		PathPattern:        "/virtualization/cluster-types/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterTypesReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterTypesReadOK), nil

}

/*
VirtualizationClusterTypesUpdate virtualization cluster types update API
*/
func (a *Client) VirtualizationClusterTypesUpdate(params *VirtualizationClusterTypesUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClusterTypesUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClusterTypesUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_cluster-types_update",
		Method:             "PUT",
		PathPattern:        "/virtualization/cluster-types/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClusterTypesUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClusterTypesUpdateOK), nil

}

/*
VirtualizationClustersCreate virtualization clusters create API
*/
func (a *Client) VirtualizationClustersCreate(params *VirtualizationClustersCreateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClustersCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClustersCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_clusters_create",
		Method:             "POST",
		PathPattern:        "/virtualization/clusters/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClustersCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClustersCreateCreated), nil

}

/*
VirtualizationClustersDelete virtualization clusters delete API
*/
func (a *Client) VirtualizationClustersDelete(params *VirtualizationClustersDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClustersDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClustersDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_clusters_delete",
		Method:             "DELETE",
		PathPattern:        "/virtualization/clusters/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClustersDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClustersDeleteNoContent), nil

}

/*
VirtualizationClustersList virtualization clusters list API
*/
func (a *Client) VirtualizationClustersList(params *VirtualizationClustersListParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClustersListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClustersListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_clusters_list",
		Method:             "GET",
		PathPattern:        "/virtualization/clusters/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClustersListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClustersListOK), nil

}

/*
VirtualizationClustersPartialUpdate virtualization clusters partial update API
*/
func (a *Client) VirtualizationClustersPartialUpdate(params *VirtualizationClustersPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClustersPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClustersPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_clusters_partial_update",
		Method:             "PATCH",
		PathPattern:        "/virtualization/clusters/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClustersPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClustersPartialUpdateOK), nil

}

/*
VirtualizationClustersRead virtualization clusters read API
*/
func (a *Client) VirtualizationClustersRead(params *VirtualizationClustersReadParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClustersReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClustersReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_clusters_read",
		Method:             "GET",
		PathPattern:        "/virtualization/clusters/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClustersReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClustersReadOK), nil

}

/*
VirtualizationClustersUpdate virtualization clusters update API
*/
func (a *Client) VirtualizationClustersUpdate(params *VirtualizationClustersUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationClustersUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationClustersUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_clusters_update",
		Method:             "PUT",
		PathPattern:        "/virtualization/clusters/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationClustersUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationClustersUpdateOK), nil

}

/*
VirtualizationInterfacesCreate virtualization interfaces create API
*/
func (a *Client) VirtualizationInterfacesCreate(params *VirtualizationInterfacesCreateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationInterfacesCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationInterfacesCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_interfaces_create",
		Method:             "POST",
		PathPattern:        "/virtualization/interfaces/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationInterfacesCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationInterfacesCreateCreated), nil

}

/*
VirtualizationInterfacesDelete virtualization interfaces delete API
*/
func (a *Client) VirtualizationInterfacesDelete(params *VirtualizationInterfacesDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationInterfacesDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationInterfacesDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_interfaces_delete",
		Method:             "DELETE",
		PathPattern:        "/virtualization/interfaces/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationInterfacesDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationInterfacesDeleteNoContent), nil

}

/*
VirtualizationInterfacesList virtualization interfaces list API
*/
func (a *Client) VirtualizationInterfacesList(params *VirtualizationInterfacesListParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationInterfacesListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationInterfacesListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_interfaces_list",
		Method:             "GET",
		PathPattern:        "/virtualization/interfaces/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationInterfacesListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationInterfacesListOK), nil

}

/*
VirtualizationInterfacesPartialUpdate virtualization interfaces partial update API
*/
func (a *Client) VirtualizationInterfacesPartialUpdate(params *VirtualizationInterfacesPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationInterfacesPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationInterfacesPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_interfaces_partial_update",
		Method:             "PATCH",
		PathPattern:        "/virtualization/interfaces/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationInterfacesPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationInterfacesPartialUpdateOK), nil

}

/*
VirtualizationInterfacesRead virtualization interfaces read API
*/
func (a *Client) VirtualizationInterfacesRead(params *VirtualizationInterfacesReadParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationInterfacesReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationInterfacesReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_interfaces_read",
		Method:             "GET",
		PathPattern:        "/virtualization/interfaces/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationInterfacesReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationInterfacesReadOK), nil

}

/*
VirtualizationInterfacesUpdate virtualization interfaces update API
*/
func (a *Client) VirtualizationInterfacesUpdate(params *VirtualizationInterfacesUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationInterfacesUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationInterfacesUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_interfaces_update",
		Method:             "PUT",
		PathPattern:        "/virtualization/interfaces/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationInterfacesUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationInterfacesUpdateOK), nil

}

/*
VirtualizationVirtualMachinesCreate virtualization virtual machines create API
*/
func (a *Client) VirtualizationVirtualMachinesCreate(params *VirtualizationVirtualMachinesCreateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationVirtualMachinesCreateCreated, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationVirtualMachinesCreateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_virtual-machines_create",
		Method:             "POST",
		PathPattern:        "/virtualization/virtual-machines/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationVirtualMachinesCreateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationVirtualMachinesCreateCreated), nil

}

/*
VirtualizationVirtualMachinesDelete virtualization virtual machines delete API
*/
func (a *Client) VirtualizationVirtualMachinesDelete(params *VirtualizationVirtualMachinesDeleteParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationVirtualMachinesDeleteNoContent, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationVirtualMachinesDeleteParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_virtual-machines_delete",
		Method:             "DELETE",
		PathPattern:        "/virtualization/virtual-machines/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationVirtualMachinesDeleteReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationVirtualMachinesDeleteNoContent), nil

}

/*
VirtualizationVirtualMachinesList virtualization virtual machines list API
*/
func (a *Client) VirtualizationVirtualMachinesList(params *VirtualizationVirtualMachinesListParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationVirtualMachinesListOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationVirtualMachinesListParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_virtual-machines_list",
		Method:             "GET",
		PathPattern:        "/virtualization/virtual-machines/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationVirtualMachinesListReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationVirtualMachinesListOK), nil

}

/*
VirtualizationVirtualMachinesPartialUpdate virtualization virtual machines partial update API
*/
func (a *Client) VirtualizationVirtualMachinesPartialUpdate(params *VirtualizationVirtualMachinesPartialUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationVirtualMachinesPartialUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationVirtualMachinesPartialUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_virtual-machines_partial_update",
		Method:             "PATCH",
		PathPattern:        "/virtualization/virtual-machines/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationVirtualMachinesPartialUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationVirtualMachinesPartialUpdateOK), nil

}

/*
VirtualizationVirtualMachinesRead virtualization virtual machines read API
*/
func (a *Client) VirtualizationVirtualMachinesRead(params *VirtualizationVirtualMachinesReadParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationVirtualMachinesReadOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationVirtualMachinesReadParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_virtual-machines_read",
		Method:             "GET",
		PathPattern:        "/virtualization/virtual-machines/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationVirtualMachinesReadReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationVirtualMachinesReadOK), nil

}

/*
VirtualizationVirtualMachinesUpdate virtualization virtual machines update API
*/
func (a *Client) VirtualizationVirtualMachinesUpdate(params *VirtualizationVirtualMachinesUpdateParams, authInfo runtime.ClientAuthInfoWriter) (*VirtualizationVirtualMachinesUpdateOK, error) {
	// TODO: Validate the params before sending
	if params == nil {
		params = NewVirtualizationVirtualMachinesUpdateParams()
	}

	result, err := a.transport.Submit(&runtime.ClientOperation{
		ID:                 "virtualization_virtual-machines_update",
		Method:             "PUT",
		PathPattern:        "/virtualization/virtual-machines/{id}/",
		ProducesMediaTypes: []string{"application/json"},
		ConsumesMediaTypes: []string{"application/json"},
		Schemes:            []string{"http"},
		Params:             params,
		Reader:             &VirtualizationVirtualMachinesUpdateReader{formats: a.formats},
		AuthInfo:           authInfo,
		Context:            params.Context,
		Client:             params.HTTPClient,
	})
	if err != nil {
		return nil, err
	}
	return result.(*VirtualizationVirtualMachinesUpdateOK), nil

}

// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
	a.transport = transport
}
