...

Source file src/kubevirt.io/client-go/kubecli/vmi.go

Documentation: kubevirt.io/client-go/kubecli

     1  /*
     2   * This file is part of the KubeVirt project
     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   * Copyright 2017 Red Hat, Inc.
    17   *
    18   */
    19  
    20  package kubecli
    21  
    22  import (
    23  	"context"
    24  	"fmt"
    25  	"net/http"
    26  	"net/url"
    27  	"strconv"
    28  	"strings"
    29  	"time"
    30  
    31  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    32  	"k8s.io/apimachinery/pkg/types"
    33  	"k8s.io/client-go/kubernetes"
    34  	"k8s.io/client-go/rest"
    35  
    36  	v1 "kubevirt.io/api/core/v1"
    37  	kvcorev1 "kubevirt.io/client-go/generated/kubevirt/clientset/versioned/typed/core/v1"
    38  )
    39  
    40  func (k *kubevirt) VirtualMachineInstance(namespace string) VirtualMachineInstanceInterface {
    41  	return &vmis{
    42  		VirtualMachineInstanceInterface: k.GeneratedKubeVirtClient().KubevirtV1().VirtualMachineInstances(namespace),
    43  		restClient:                      k.restClient,
    44  		config:                          k.config,
    45  		clientSet:                       k.Clientset,
    46  		namespace:                       namespace,
    47  		resource:                        "virtualmachineinstances",
    48  	}
    49  }
    50  
    51  type vmis struct {
    52  	kvcorev1.VirtualMachineInstanceInterface
    53  	restClient *rest.RESTClient
    54  	config     *rest.Config
    55  	clientSet  *kubernetes.Clientset
    56  	namespace  string
    57  	resource   string
    58  	master     string
    59  	kubeconfig string
    60  }
    61  
    62  func (v *vmis) USBRedir(name string) (kvcorev1.StreamInterface, error) {
    63  	return kvcorev1.AsyncSubresourceHelper(v.config, v.resource, v.namespace, name, "usbredir", url.Values{})
    64  }
    65  
    66  func (v *vmis) VNC(name string) (kvcorev1.StreamInterface, error) {
    67  	return kvcorev1.AsyncSubresourceHelper(v.config, v.resource, v.namespace, name, "vnc", url.Values{})
    68  }
    69  
    70  func (v *vmis) PortForward(name string, port int, protocol string) (kvcorev1.StreamInterface, error) {
    71  	return kvcorev1.AsyncSubresourceHelper(v.config, v.resource, v.namespace, name, buildPortForwardResourcePath(port, protocol), url.Values{})
    72  }
    73  
    74  func buildPortForwardResourcePath(port int, protocol string) string {
    75  	resource := strings.Builder{}
    76  	resource.WriteString("portforward/")
    77  	resource.WriteString(strconv.Itoa(port))
    78  
    79  	if len(protocol) > 0 {
    80  		resource.WriteString("/")
    81  		resource.WriteString(protocol)
    82  	}
    83  
    84  	return resource.String()
    85  }
    86  
    87  type connectionStruct struct {
    88  	con kvcorev1.StreamInterface
    89  	err error
    90  }
    91  
    92  func (v *vmis) SerialConsole(name string, options *kvcorev1.SerialConsoleOptions) (kvcorev1.StreamInterface, error) {
    93  
    94  	if options != nil && options.ConnectionTimeout != 0 {
    95  		timeoutChan := time.Tick(options.ConnectionTimeout)
    96  		connectionChan := make(chan connectionStruct)
    97  
    98  		go func() {
    99  			for {
   100  
   101  				select {
   102  				case <-timeoutChan:
   103  					connectionChan <- connectionStruct{
   104  						con: nil,
   105  						err: fmt.Errorf("Timeout trying to connect to the virtual machine instance"),
   106  					}
   107  					return
   108  				default:
   109  				}
   110  
   111  				con, err := kvcorev1.AsyncSubresourceHelper(v.config, v.resource, v.namespace, name, "console", url.Values{})
   112  				if err != nil {
   113  					asyncSubresourceError, ok := err.(*kvcorev1.AsyncSubresourceError)
   114  					// return if response status code does not equal to 400
   115  					if !ok || asyncSubresourceError.GetStatusCode() != http.StatusBadRequest {
   116  						connectionChan <- connectionStruct{con: nil, err: err}
   117  						return
   118  					}
   119  
   120  					time.Sleep(1 * time.Second)
   121  					continue
   122  				}
   123  
   124  				connectionChan <- connectionStruct{con: con, err: nil}
   125  				return
   126  			}
   127  		}()
   128  		conStruct := <-connectionChan
   129  		return conStruct.con, conStruct.err
   130  	} else {
   131  		return kvcorev1.AsyncSubresourceHelper(v.config, v.resource, v.namespace, name, "console", url.Values{})
   132  	}
   133  }
   134  
   135  func (v *vmis) Get(ctx context.Context, name string, options metav1.GetOptions) (vmi *v1.VirtualMachineInstance, err error) {
   136  	vmi, err = v.VirtualMachineInstanceInterface.Get(ctx, name, options)
   137  	vmi.SetGroupVersionKind(v1.VirtualMachineInstanceGroupVersionKind)
   138  	return
   139  }
   140  
   141  func (v *vmis) List(ctx context.Context, options metav1.ListOptions) (vmiList *v1.VirtualMachineInstanceList, err error) {
   142  	vmiList, err = v.VirtualMachineInstanceInterface.List(ctx, options)
   143  	for i := range vmiList.Items {
   144  		vmiList.Items[i].SetGroupVersionKind(v1.VirtualMachineInstanceGroupVersionKind)
   145  	}
   146  	return
   147  }
   148  
   149  func (v *vmis) Create(ctx context.Context, vmi *v1.VirtualMachineInstance, opts metav1.CreateOptions) (result *v1.VirtualMachineInstance, err error) {
   150  	result, err = v.VirtualMachineInstanceInterface.Create(ctx, vmi, opts)
   151  	result.SetGroupVersionKind(v1.VirtualMachineInstanceGroupVersionKind)
   152  	return
   153  }
   154  
   155  func (v *vmis) Update(ctx context.Context, vmi *v1.VirtualMachineInstance, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstance, err error) {
   156  	result, err = v.VirtualMachineInstanceInterface.Update(ctx, vmi, opts)
   157  	result.SetGroupVersionKind(v1.VirtualMachineInstanceGroupVersionKind)
   158  	return
   159  }
   160  
   161  func (v *vmis) Delete(ctx context.Context, name string, options metav1.DeleteOptions) error {
   162  	return v.VirtualMachineInstanceInterface.Delete(ctx, name, options)
   163  }
   164  
   165  func (v *vmis) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, patchOptions metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstance, err error) {
   166  	return v.VirtualMachineInstanceInterface.Patch(ctx, name, pt, data, patchOptions, subresources...)
   167  }
   168  
   169  func (v *vmis) VSOCK(name string, options *v1.VSOCKOptions) (kvcorev1.StreamInterface, error) {
   170  	if options == nil || options.TargetPort == 0 {
   171  		return nil, fmt.Errorf("target port is required but not provided")
   172  	}
   173  	queryParams := url.Values{}
   174  	queryParams.Add("port", strconv.FormatUint(uint64(options.TargetPort), 10))
   175  	useTLS := true
   176  	if options.UseTLS != nil {
   177  		useTLS = *options.UseTLS
   178  	}
   179  	queryParams.Add("tls", strconv.FormatBool(useTLS))
   180  	return kvcorev1.AsyncSubresourceHelper(v.config, v.resource, v.namespace, name, "vsock", queryParams)
   181  }
   182  

View as plain text