github.com/upcmd/up@v0.8.1-0.20230108151705-ad8b797bf04f/tests/functests/c0178.yml (about) 1 doc_meta: | 2 folder: object-oriented 3 title: access and register sub object 2 4 head: | 5 * Access sub element and register the object 6 * Adapt the object for loop 7 8 sections: 9 - title: Demo 10 log: yes 11 12 tasks: 13 - 14 name: task 15 task: 16 - 17 func: cmd 18 desc: | 19 this will get a response of: 20 Output: { 21 "LoadBalancerDescriptions": [ 22 { 23 "LoadBalancerName": "xx-elb", 24 "DNSName": "x-y-z.elb.amazonaws.com", 25 ........... 26 "Instances": [ 27 { 28 "InstanceId": "i-1234567890" 29 }, 30 { 31 "InstanceId": "i-9876543210" 32 } 33 ], 34 ........... 35 } 36 ] 37 } 38 do: 39 - name: print 40 desc: mock only - pretent to call it 41 cmd: 'aws elb describe-load-balancers --load-balancer-names my-web-app-elb' 42 43 - 44 func: cmd 45 vars: 46 last_result: 47 Output: | 48 { 49 "LoadBalancerDescriptions": [ 50 { 51 "LoadBalancerName": "xx-elb", 52 "DNSName": "x-y-z.elb.amazonaws.com", 53 "Instances": [ 54 { 55 "InstanceId": "i-1234567890" 56 }, 57 { 58 "InstanceId": "i-9876543210" 59 } 60 ], 61 } 62 ] 63 } 64 dvars: 65 - name: elb 66 value: '{{.last_result.Output}}' 67 desc: | 68 this will map the reponse to name of elb 69 then convert it to an object and register to cache 70 the object name would be kept the same called elb, so now elb is a object instead of string content 71 it is marked as in taskScope, means that it will be available to be acessible in the next func call in Main task 72 flags: 73 - keepName 74 - toObj 75 - reg 76 - taskScope 77 - v 78 79 - name: void 80 desc: | 81 index .elb.LoadBalancerDescriptions 0 will locate the sub object of Instances 82 objToYml template func is chained and called to to convert the objToYml 83 then the yml is again converted to an object 84 then registered as name of instances_1 which is a object 85 the dvar name "void" means it does not register the string value to cached 86 87 * note: instances_1 is a object of type of *interface{} 88 89 "instances_1": (*[]interface {})({ 90 { 91 "InstanceId": "i-02f5cf3cdb572d627" 92 }, 93 { 94 "InstanceId": "i-00e53fd8688e9193a" 95 } 96 }) 97 98 So you can use access and reference instances_1 in template value, however this internal type will not match what is required for loop tag, even though it looks like it is iteratable 99 100 You can access, reference to sub element and iterate it using the go template though, for example: 101 '{{(index .instances_1. 0).Instances}}' => "i-02f5cf3cdb572d627" 102 value: '{{(index .elb.LoadBalancerDescriptions 0).Instances |objToYml|ymlToObj|reg "instances_1"}}' 103 104 - name: void 105 desc: | 106 regObj is a template func as short hand to register the chain through object into the cache 107 the name of the object is instances_2 108 value: '{{(index .elb.LoadBalancerDescriptions 0).Instances |regObj "instances_2"}}' 109 do: 110 - name: printObj 111 cmd: instances_1 112 113 - name: printObj 114 cmd: instances_2 115 116 - 117 func: cmd 118 do: 119 120 - name: inspect 121 cmd: 122 - debug_vars 123 124 - 125 func: cmd 126 dvars: 127 - name: instances_3 128 desc: | 129 index .elb.LoadBalancerDescriptions 0 will locate the sub object of Instances 130 objToYml template func is chained and called to to convert the objToYml, now the result is yml string 131 toObj flag decorate the behavior to convert the yml string to an object and the object name is kept the same as instances_3 132 133 * note the different of instances_3 and ( instances_1 or instances_2) is the internal data type 134 135 instances_3 data type is a plain slice/array and we can use this for the loop tag 136 { 137 { 138 "InstanceId": "i-02f5cf3cdb572d627" 139 }, 140 { 141 "InstanceId": "i-00e53fd8688e9193a" 142 } 143 } 144 145 value: '{{(index .elb.LoadBalancerDescriptions 0).Instances | objToYml}}' 146 flags: 147 - v 148 - keepName 149 - toObj 150 loop: 'instances_3' 151 do: 152 - name: print 153 cmd: '{{.loopitem.InstanceId}}'