sigs.k8s.io/cluster-api@v1.7.1/internal/contract/infrastructure_machine.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     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 contract
    18  
    19  import (
    20  	"encoding/json"
    21  	"strings"
    22  	"sync"
    23  
    24  	"github.com/pkg/errors"
    25  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    26  
    27  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    28  )
    29  
    30  // InfrastructureMachineContract encodes information about the Cluster API contract for InfrastructureMachine objects
    31  // like DockerMachines, AWS Machines, etc.
    32  type InfrastructureMachineContract struct{}
    33  
    34  var infrastructureMachine *InfrastructureMachineContract
    35  var onceInfrastructureMachine sync.Once
    36  
    37  // InfrastructureMachine provide access to the information about the Cluster API contract for InfrastructureMachine objects.
    38  func InfrastructureMachine() *InfrastructureMachineContract {
    39  	onceInfrastructureMachine.Do(func() {
    40  		infrastructureMachine = &InfrastructureMachineContract{}
    41  	})
    42  	return infrastructureMachine
    43  }
    44  
    45  // Ready provides access to status.ready field in an InfrastructureMachine object.
    46  func (m *InfrastructureMachineContract) Ready() *Bool {
    47  	return &Bool{
    48  		path: []string{"status", "ready"},
    49  	}
    50  }
    51  
    52  // FailureReason provides access to the status.failureReason field in an InfrastructureMachine object. Note that this field is optional.
    53  func (m *InfrastructureMachineContract) FailureReason() *String {
    54  	return &String{
    55  		path: []string{"status", "failureReason"},
    56  	}
    57  }
    58  
    59  // FailureMessage provides access to the status.failureMessage field in an InfrastructureMachine object. Note that this field is optional.
    60  func (m *InfrastructureMachineContract) FailureMessage() *String {
    61  	return &String{
    62  		path: []string{"status", "failureMessage"},
    63  	}
    64  }
    65  
    66  // Addresses provides access to the status.addresses field in an InfrastructureMachine object. Note that this field is optional.
    67  func (m *InfrastructureMachineContract) Addresses() *MachineAddresses {
    68  	return &MachineAddresses{
    69  		path: []string{"status", "addresses"},
    70  	}
    71  }
    72  
    73  // ProviderID provides access to the spec.providerID field in an InfrastructureMachine object.
    74  func (m *InfrastructureMachineContract) ProviderID() *String {
    75  	return &String{
    76  		path: []string{"spec", "providerID"},
    77  	}
    78  }
    79  
    80  // FailureDomain provides access to the spec.failureDomain field in an InfrastructureMachine object. Note that this field is optional.
    81  func (m *InfrastructureMachineContract) FailureDomain() *String {
    82  	return &String{
    83  		path: []string{"spec", "failureDomain"},
    84  	}
    85  }
    86  
    87  // MachineAddresses represents an accessor to a []clusterv1.MachineAddress path value.
    88  type MachineAddresses struct {
    89  	path Path
    90  }
    91  
    92  // Path returns the path to the []clusterv1.MachineAddress value.
    93  func (m *MachineAddresses) Path() Path {
    94  	return m.path
    95  }
    96  
    97  // Get gets the metav1.MachineAddressList value.
    98  func (m *MachineAddresses) Get(obj *unstructured.Unstructured) (*[]clusterv1.MachineAddress, error) {
    99  	slice, ok, err := unstructured.NestedSlice(obj.UnstructuredContent(), m.path...)
   100  	if err != nil {
   101  		return nil, errors.Wrapf(err, "failed to get %s from object", "."+strings.Join(m.path, "."))
   102  	}
   103  	if !ok {
   104  		return nil, errors.Wrapf(ErrFieldNotFound, "path %s", "."+strings.Join(m.path, "."))
   105  	}
   106  
   107  	addresses := make([]clusterv1.MachineAddress, len(slice))
   108  	s, err := json.Marshal(slice)
   109  	if err != nil {
   110  		return nil, errors.Wrapf(err, "failed to marshall field at %s to json", "."+strings.Join(m.path, "."))
   111  	}
   112  	err = json.Unmarshal(s, &addresses)
   113  	if err != nil {
   114  		return nil, errors.Wrapf(err, "failed to unmarshall field at %s to json", "."+strings.Join(m.path, "."))
   115  	}
   116  
   117  	return &addresses, nil
   118  }
   119  
   120  // Set sets the []clusterv1.MachineAddress value in the path.
   121  func (m *MachineAddresses) Set(obj *unstructured.Unstructured, values []clusterv1.MachineAddress) error {
   122  	slice := make([]interface{}, len(values))
   123  	s, err := json.Marshal(values)
   124  	if err != nil {
   125  		return errors.Wrapf(err, "failed to marshall supplied values to json for path %s", "."+strings.Join(m.path, "."))
   126  	}
   127  	err = json.Unmarshal(s, &slice)
   128  	if err != nil {
   129  		return errors.Wrapf(err, "failed to unmarshall supplied values to json for path %s", "."+strings.Join(m.path, "."))
   130  	}
   131  
   132  	if err := unstructured.SetNestedField(obj.UnstructuredContent(), slice, m.path...); err != nil {
   133  		return errors.Wrapf(err, "failed to set path %s of object %v", "."+strings.Join(m.path, "."), obj.GroupVersionKind())
   134  	}
   135  	return nil
   136  }