github.com/vmware/govmomi@v0.43.0/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  				fi := NewFileItem(u, item)
   149  				fi.Thumbprint = device.SslThumbprint
   150  
   151  				info.Items = append(info.Items, fi)
   152  
   153  				break
   154  			}
   155  		}
   156  	}
   157  
   158  	return info, nil
   159  }
   160  
   161  func (l *Lease) Wait(ctx context.Context, items []types.OvfFileItem) (*LeaseInfo, error) {
   162  	var lease mo.HttpNfcLease
   163  
   164  	pc := property.DefaultCollector(l.c)
   165  	err := property.Wait(ctx, pc, l.Reference(), []string{"state", "info", "error"}, func(pc []types.PropertyChange) bool {
   166  		done := false
   167  
   168  		for _, c := range pc {
   169  			if c.Val == nil {
   170  				continue
   171  			}
   172  
   173  			switch c.Name {
   174  			case "error":
   175  				val := c.Val.(types.LocalizedMethodFault)
   176  				lease.Error = &val
   177  				done = true
   178  			case "info":
   179  				val := c.Val.(types.HttpNfcLeaseInfo)
   180  				lease.Info = &val
   181  			case "state":
   182  				lease.State = c.Val.(types.HttpNfcLeaseState)
   183  				if lease.State != types.HttpNfcLeaseStateInitializing {
   184  					done = true
   185  				}
   186  			}
   187  		}
   188  
   189  		return done
   190  	})
   191  
   192  	if err != nil {
   193  		return nil, err
   194  	}
   195  
   196  	if lease.State == types.HttpNfcLeaseStateReady {
   197  		return l.newLeaseInfo(lease.Info, items)
   198  	}
   199  
   200  	if lease.Error != nil {
   201  		return nil, &task.Error{LocalizedMethodFault: lease.Error}
   202  	}
   203  
   204  	return nil, fmt.Errorf("unexpected nfc lease state: %s", lease.State)
   205  }
   206  
   207  func (l *Lease) StartUpdater(ctx context.Context, info *LeaseInfo) *LeaseUpdater {
   208  	return newLeaseUpdater(ctx, l, info)
   209  }
   210  
   211  func (l *Lease) Upload(ctx context.Context, item FileItem, f io.Reader, opts soap.Upload) error {
   212  	if opts.Progress == nil {
   213  		opts.Progress = item
   214  	}
   215  
   216  	// Non-disk files (such as .iso) use the PUT method.
   217  	// Overwrite: t header is also required in this case (ovftool does the same)
   218  	if item.Create {
   219  		opts.Method = "PUT"
   220  		opts.Headers = map[string]string{
   221  			"Overwrite": "t",
   222  		}
   223  	} else {
   224  		opts.Method = "POST"
   225  		opts.Type = "application/x-vnd.vmware-streamVmdk"
   226  	}
   227  
   228  	return l.c.Upload(ctx, f, item.URL, &opts)
   229  }
   230  
   231  func (l *Lease) DownloadFile(ctx context.Context, file string, item FileItem, opts soap.Download) error {
   232  	if opts.Progress == nil {
   233  		opts.Progress = item
   234  	}
   235  
   236  	return l.c.DownloadFile(ctx, file, item.URL, &opts)
   237  }