github.com/vmware/govmomi@v0.37.2/nfc/lease.go (about)

     1  /*
     2  Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package nfc
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"io"
    23  	"path"
    24  
    25  	"github.com/vmware/govmomi/property"
    26  	"github.com/vmware/govmomi/task"
    27  	"github.com/vmware/govmomi/vim25"
    28  	"github.com/vmware/govmomi/vim25/methods"
    29  	"github.com/vmware/govmomi/vim25/mo"
    30  	"github.com/vmware/govmomi/vim25/soap"
    31  	"github.com/vmware/govmomi/vim25/types"
    32  )
    33  
    34  type Lease struct {
    35  	types.ManagedObjectReference
    36  
    37  	c *vim25.Client
    38  }
    39  
    40  func NewLease(c *vim25.Client, ref types.ManagedObjectReference) *Lease {
    41  	return &Lease{ref, c}
    42  }
    43  
    44  // Abort wraps methods.Abort
    45  func (l *Lease) Abort(ctx context.Context, fault *types.LocalizedMethodFault) error {
    46  	req := types.HttpNfcLeaseAbort{
    47  		This:  l.Reference(),
    48  		Fault: fault,
    49  	}
    50  
    51  	_, err := methods.HttpNfcLeaseAbort(ctx, l.c, &req)
    52  	if err != nil {
    53  		return err
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  // Complete wraps methods.Complete
    60  func (l *Lease) Complete(ctx context.Context) error {
    61  	req := types.HttpNfcLeaseComplete{
    62  		This: l.Reference(),
    63  	}
    64  
    65  	_, err := methods.HttpNfcLeaseComplete(ctx, l.c, &req)
    66  	if err != nil {
    67  		return err
    68  	}
    69  
    70  	return nil
    71  }
    72  
    73  // GetManifest wraps methods.GetManifest
    74  func (l *Lease) GetManifest(ctx context.Context) ([]types.HttpNfcLeaseManifestEntry, error) {
    75  	req := types.HttpNfcLeaseGetManifest{
    76  		This: l.Reference(),
    77  	}
    78  
    79  	res, err := methods.HttpNfcLeaseGetManifest(ctx, l.c, &req)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	return res.Returnval, nil
    85  }
    86  
    87  // Progress wraps methods.Progress
    88  func (l *Lease) Progress(ctx context.Context, percent int32) error {
    89  	req := types.HttpNfcLeaseProgress{
    90  		This:    l.Reference(),
    91  		Percent: percent,
    92  	}
    93  
    94  	_, err := methods.HttpNfcLeaseProgress(ctx, l.c, &req)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	return nil
   100  }
   101  
   102  type LeaseInfo struct {
   103  	types.HttpNfcLeaseInfo
   104  
   105  	Items []FileItem
   106  }
   107  
   108  func (l *Lease) newLeaseInfo(li *types.HttpNfcLeaseInfo, items []types.OvfFileItem) (*LeaseInfo, error) {
   109  	info := &LeaseInfo{
   110  		HttpNfcLeaseInfo: *li,
   111  	}
   112  
   113  	for _, device := range li.DeviceUrl {
   114  		u, err := l.c.ParseURL(device.Url)
   115  		if err != nil {
   116  			return nil, err
   117  		}
   118  
   119  		if device.SslThumbprint != "" {
   120  			// TODO: prefer host management IP
   121  			l.c.SetThumbprint(u.Host, device.SslThumbprint)
   122  		}
   123  
   124  		if len(items) == 0 {
   125  			// this is an export
   126  			item := types.OvfFileItem{
   127  				DeviceId: device.Key,
   128  				Path:     device.TargetId,
   129  				Size:     device.FileSize,
   130  			}
   131  
   132  			if item.Size == 0 {
   133  				item.Size = li.TotalDiskCapacityInKB * 1024
   134  			}
   135  
   136  			if item.Path == "" {
   137  				item.Path = path.Base(device.Url)
   138  			}
   139  
   140  			info.Items = append(info.Items, NewFileItem(u, item))
   141  
   142  			continue
   143  		}
   144  
   145  		// this is an import
   146  		for _, item := range items {
   147  			if device.ImportKey == item.DeviceId {
   148  				info.Items = append(info.Items, NewFileItem(u, item))
   149  				break
   150  			}
   151  		}
   152  	}
   153  
   154  	return info, nil
   155  }
   156  
   157  func (l *Lease) Wait(ctx context.Context, items []types.OvfFileItem) (*LeaseInfo, error) {
   158  	var lease mo.HttpNfcLease
   159  
   160  	pc := property.DefaultCollector(l.c)
   161  	err := property.Wait(ctx, pc, l.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool {
   162  		done := false
   163  
   164  		for _, c := range pc {
   165  			if c.Val == nil {
   166  				continue
   167  			}
   168  
   169  			switch c.Name {
   170  			case "error":
   171  				val := c.Val.(types.LocalizedMethodFault)
   172  				lease.Error = &val
   173  				done = true
   174  			case "info":
   175  				val := c.Val.(types.HttpNfcLeaseInfo)
   176  				lease.Info = &val
   177  			case "state":
   178  				lease.State = c.Val.(types.HttpNfcLeaseState)
   179  				if lease.State != types.HttpNfcLeaseStateInitializing {
   180  					done = true
   181  				}
   182  			}
   183  		}
   184  
   185  		return done
   186  	})
   187  
   188  	if err != nil {
   189  		return nil, err
   190  	}
   191  
   192  	if lease.State == types.HttpNfcLeaseStateReady {
   193  		return l.newLeaseInfo(lease.Info, items)
   194  	}
   195  
   196  	if lease.Error != nil {
   197  		return nil, &task.Error{LocalizedMethodFault: lease.Error}
   198  	}
   199  
   200  	return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
   201  }
   202  
   203  func (l *Lease) StartUpdater(ctx context.Context, info *LeaseInfo) *LeaseUpdater {
   204  	return newLeaseUpdater(ctx, l, info)
   205  }
   206  
   207  func (l *Lease) Upload(ctx context.Context, item FileItem, f io.Reader, opts soap.Upload) error {
   208  	if opts.Progress == nil {
   209  		opts.Progress = item
   210  	}
   211  
   212  	// Non-disk files (such as .iso) use the PUT method.
   213  	// Overwrite: t header is also required in this case (ovftool does the same)
   214  	if item.Create {
   215  		opts.Method = "PUT"
   216  		opts.Headers = map[string]string{
   217  			"Overwrite": "t",
   218  		}
   219  	} else {
   220  		opts.Method = "POST"
   221  		opts.Type = "application/x-vnd.vmware-streamVmdk"
   222  	}
   223  
   224  	return l.c.Upload(ctx, f, item.URL, &opts)
   225  }
   226  
   227  func (l *Lease) DownloadFile(ctx context.Context, file string, item FileItem, opts soap.Download) error {
   228  	if opts.Progress == nil {
   229  		opts.Progress = item
   230  	}
   231  
   232  	return l.c.DownloadFile(ctx, file, item.URL, &opts)
   233  }