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 }