github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/rpc/resource_provisioner.go (about)

     1  package rpc
     2  
     3  import (
     4  	"net/rpc"
     5  
     6  	"github.com/hashicorp/terraform/terraform"
     7  )
     8  
     9  // ResourceProvisioner is an implementation of terraform.ResourceProvisioner
    10  // that communicates over RPC.
    11  type ResourceProvisioner struct {
    12  	Broker *muxBroker
    13  	Client *rpc.Client
    14  	Name   string
    15  }
    16  
    17  func (p *ResourceProvisioner) Validate(c *terraform.ResourceConfig) ([]string, []error) {
    18  	var resp ResourceProvisionerValidateResponse
    19  	args := ResourceProvisionerValidateArgs{
    20  		Config: c,
    21  	}
    22  
    23  	err := p.Client.Call(p.Name+".Validate", &args, &resp)
    24  	if err != nil {
    25  		return nil, []error{err}
    26  	}
    27  
    28  	var errs []error
    29  	if len(resp.Errors) > 0 {
    30  		errs = make([]error, len(resp.Errors))
    31  		for i, err := range resp.Errors {
    32  			errs[i] = err
    33  		}
    34  	}
    35  
    36  	return resp.Warnings, errs
    37  }
    38  
    39  func (p *ResourceProvisioner) Apply(
    40  	output terraform.UIOutput,
    41  	s *terraform.InstanceState,
    42  	c *terraform.ResourceConfig) error {
    43  	id := p.Broker.NextId()
    44  	go acceptAndServe(p.Broker, id, "UIOutput", &UIOutputServer{
    45  		UIOutput: output,
    46  	})
    47  
    48  	var resp ResourceProvisionerApplyResponse
    49  	args := &ResourceProvisionerApplyArgs{
    50  		OutputId: id,
    51  		State:    s,
    52  		Config:   c,
    53  	}
    54  
    55  	err := p.Client.Call(p.Name+".Apply", args, &resp)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	if resp.Error != nil {
    60  		err = resp.Error
    61  	}
    62  
    63  	return err
    64  }
    65  
    66  func (p *ResourceProvisioner) Close() error {
    67  	return p.Client.Close()
    68  }
    69  
    70  type ResourceProvisionerValidateArgs struct {
    71  	Config *terraform.ResourceConfig
    72  }
    73  
    74  type ResourceProvisionerValidateResponse struct {
    75  	Warnings []string
    76  	Errors   []*BasicError
    77  }
    78  
    79  type ResourceProvisionerApplyArgs struct {
    80  	OutputId uint32
    81  	State    *terraform.InstanceState
    82  	Config   *terraform.ResourceConfig
    83  }
    84  
    85  type ResourceProvisionerApplyResponse struct {
    86  	Error *BasicError
    87  }
    88  
    89  // ResourceProvisionerServer is a net/rpc compatible structure for serving
    90  // a ResourceProvisioner. This should not be used directly.
    91  type ResourceProvisionerServer struct {
    92  	Broker      *muxBroker
    93  	Provisioner terraform.ResourceProvisioner
    94  }
    95  
    96  func (s *ResourceProvisionerServer) Apply(
    97  	args *ResourceProvisionerApplyArgs,
    98  	result *ResourceProvisionerApplyResponse) error {
    99  	conn, err := s.Broker.Dial(args.OutputId)
   100  	if err != nil {
   101  		*result = ResourceProvisionerApplyResponse{
   102  			Error: NewBasicError(err),
   103  		}
   104  		return nil
   105  	}
   106  	client := rpc.NewClient(conn)
   107  	defer client.Close()
   108  
   109  	output := &UIOutput{
   110  		Client: client,
   111  		Name:   "UIOutput",
   112  	}
   113  
   114  	err = s.Provisioner.Apply(output, args.State, args.Config)
   115  	*result = ResourceProvisionerApplyResponse{
   116  		Error: NewBasicError(err),
   117  	}
   118  	return nil
   119  }
   120  
   121  func (s *ResourceProvisionerServer) Validate(
   122  	args *ResourceProvisionerValidateArgs,
   123  	reply *ResourceProvisionerValidateResponse) error {
   124  	warns, errs := s.Provisioner.Validate(args.Config)
   125  	berrs := make([]*BasicError, len(errs))
   126  	for i, err := range errs {
   127  		berrs[i] = NewBasicError(err)
   128  	}
   129  	*reply = ResourceProvisionerValidateResponse{
   130  		Warnings: warns,
   131  		Errors:   berrs,
   132  	}
   133  	return nil
   134  }