<div dir="ltr">You are making this to hard on yourself :). Don't manage port mapping instances, manage the desired state.<div><br></div><div>Ex:</div><div><br></div><div><font face="monospace, monospace">//Staticly define the data for demonstration purposes. In production, I fetch the data from another server.</font></div><div><font face="monospace, monospace">let portForwards = [{"InternalClient":"192.168.1.<wbr>113","PortMappingDescription":<wbr>"<a href="http://192.168.1.113:9308" target="_blank">192.168.1.113:9308</a> to 9308 (UDP)","PortMappingProtocol":"<wbr>UDP","PortMappingEnabled":1,"</font></div><div><font face="monospace, monospace">RemoteHost":"","InternalPort":<wbr>9308,"ExternalPort":9308,"<wbr>ExternalPortEndRange":9308}];</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><div><font face="monospace, monospace">let basePath = "InternetGatewayDevice.WANDevi<wbr>ce.*.WANConnectionDevice.1.WAN<wbr>PPPConnection.*.PortMapping";</font></div><div><font face="monospace, monospace">declare(basePath + ".[]", null, {path: 0}); // Tell Genie we want to delete everything, this won't actually happen unless the instances don't match up (i.e. an instance was deleted)</font></div></div><div><font face="monospace, monospace"><br></font></div><div><div><font face="monospace, monospace">for (let forward of portForwards) {</font></div><div><font face="monospace, monospace">    const path = basePath + '.[' + Object.keys(forward).map(funct<wbr>ion (key) { return key + ':' + forward[key]; }).join(',') + ']';</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    log("\r\n\r\nPortForwards - Updating - " + path + "\r\n\r\n", forward);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    for (let key of Object.keys(forward)) {</font></div><div><font face="monospace, monospace">        declare(path, {path: 1}, {path: 1});</font></div><div><font face="monospace, monospace">    }</font></div><div><font face="monospace, monospace">}</font></div></div><div><br></div><div>What will happen here is on the first run of this script, the port mapping will be created. On subsequent runs, in Genie's internal state it will first delete all object instances, but then see that the desired state at the end is to have a single port mapping, with a name of "<a href="http://192.168.1.113:9308/" style="color:rgb(17,85,204);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255)" target="_blank">192.168.1.113:9308</a><span style="color:rgb(34,34,34);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>to 9308 (UDP)", protocol of UDP, etc. And so no change will be made.</span></div><div><span style="color:rgb(34,34,34);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="color:rgb(34,34,34);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">If on subsequent runs, you change any of the parameters, the previous instance will be deleted, and a new instance will be created with the given values.</span></div><div><span style="color:rgb(34,34,34);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="color:rgb(34,34,34);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Make sense?</span></div><div><span style="color:rgb(34,34,34);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="color:rgb(34,34,34);font-family:monospace,monospace;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">-dan</span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Apr 13, 2018 at 5:33 AM, George Chelidze <span dir="ltr"><<a href="mailto:george.chelidze@magticom.ge" target="_blank">george.chelidze@magticom.ge</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
As you know PortMapping object's location depends on instances for<br>
WANDevice, WANConnectionDevice and WANIPConnection nodes. So in general<br>
it's:<br>
<br>
InternetGatewayDevice.<wbr>WANDevice.{i}.<wbr>WANConnectionDevice.{i}.<wbr>WANIPConnection.{i}.<wbr>PortMapping<br>
<br>
In practice, it can be as simple as<br>
InternetGatewayDevice.<wbr>WANDevice.1.<wbr>WANConnectionDevice.1.<wbr>WANIPConnection.1.PortMapping,<br>
or with the same success, it can be<br>
InternetGatewayDevice.<wbr>WANDevice.5.<wbr>WANConnectionDevice.1.<wbr>WANIPConnection.3.PortMapping<br>
depending on vendor's implementation. You never know what instances are<br>
used, when do they change (if ever), so you have to query a device.<br>
<br>
To be able to manage this table through API, you have to:<br>
<br>
A) Find actual instances used. For this, I use the following preset<br>
called WANIPConnectionPortMapping:<br>
<br>
let wanIPConnectionPortMapping =<br>
"InternetGatewayDevice.<wbr>WANDevice.1.<wbr>WANConnectionDevice.1.<wbr>WANIPConnection.1.PortMapping"<wbr>;<br>
let portMappings =<br>
declare("<wbr>InternetGatewayDevice.<wbr>WANDevice.*.<wbr>WANConnectionDevice.*.<wbr>WANIPConnection.*.PortMapping"<wbr>,<br>
{path: Date.now()});<br>
if (portMappings.size) {<br>
  for (let portMapping of portMappings) {<br>
    wanIPConnectionPortMapping = portMapping.path;<br>
    break;<br>
  } <br>
}<br>
return {writable: false, value: [wanIPConnectionPortMapping, "xsd:string"]};<br>
<br>
As a result, I can read VirtualParameters.<wbr>WANIPConnectionPortMapping,<br>
which contains the actual path (the first one) currently used, and use<br>
it for further API calls.<br>
<br>
B) If it's possible to create a VirtualParameter which contains a<br>
writable table, it will be possible to perform whatever operations is<br>
required directly on this parameter (table) without taking care about<br>
instances used, which will simplify the whole process. Another benefit<br>
would be to use this parameter in summary_parameters.yml to display the<br>
table (as far as I understand it's not possible to use any kind of<br>
wildcards/regexp in summary_parameters.yml).<br>
<br>
So to summarize, my question is regarding second approach (B): Is it<br>
possible to create a writable virtual parameter which contains a table<br>
(not a primitive like xsd:string, xsd:unsignedInt, etc). If yes, a<br>
simple example would be great. If not, we have a workaround as described<br>
in point A, however it's not clear how to describe this table in<br>
summary_parameters.yml. Any suggestions?<br>
<br>
Regards,<br>
<br>
George Chelidze<br>
<br>
______________________________<wbr>_________________<br>
Users mailing list<br>
<a href="mailto:Users@lists.genieacs.com">Users@lists.genieacs.com</a><br>
<a href="http://lists.genieacs.com/mailman/listinfo/users" rel="noreferrer" target="_blank">http://lists.genieacs.com/<wbr>mailman/listinfo/users</a><br>
</blockquote></div><br></div>