<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Storing and deploying BGP authentication keys with NSO in NSO Developer Hub Discussions</title>
    <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4690017#M7397</link>
    <description>&lt;P&gt;You can update after the end of the transaction using a kicker. See docs here &lt;A href="https://developer.cisco.com/docs/nso/guides/#!kicker" target="_blank"&gt;https://developer.cisco.com/docs/nso/guides/#!kicker&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;You would set the kicker to react to any changes in the authentication-keys or passwords and it would trigger an action that does the sync-from. I think it might be&amp;nbsp; possible to have an expression that tests whether the key is unencrypted to make the triggering more accurate.&lt;/P&gt;
&lt;P&gt;I think you&amp;nbsp; might have to write your own action that uses the input to figure out what device to sync. That could call a partial sync. A kicker per device might also work if you want to use the existing sync-from action without parameters&lt;/P&gt;</description>
    <pubDate>Mon, 19 Sep 2022 17:54:51 GMT</pubDate>
    <dc:creator>snovello</dc:creator>
    <dc:date>2022-09-19T17:54:51Z</dc:date>
    <item>
      <title>Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4687847#M7384</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I'm working on an NSO service, that configures BGP peerings on Juniper devices.&lt;/P&gt;&lt;P&gt;I'm looking for a method to store authentication-key in an encrypted manner in my NSO service and deploying that to the device(s) via NETCONF.&lt;/P&gt;&lt;P&gt;I've tried storing authentication-key as "md5-digest-string" from tailf-common, but Junos takes the key as plaintext and encrypts it - not really what I wanted.&lt;/P&gt;&lt;P&gt;Any pointers on where to start?&lt;/P&gt;&lt;P&gt;TIA&lt;/P&gt;</description>
      <pubDate>Thu, 15 Sep 2022 12:36:50 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4687847#M7384</guid>
      <dc:creator>Ole Hansen</dc:creator>
      <dc:date>2022-09-15T12:36:50Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4687958#M7385</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;the link here &lt;A href="https://github.com/NSO-developer/ipython-superuser#decrypting-passwords" target="_blank"&gt;https://github.com/NSO-developer/ipython-superuser#decrypting-passwords&lt;/A&gt; show how you decrypt an encrypted leaf (in python). You must explicitly decrypt before passing it to the device in a template for example. &lt;/P&gt;
&lt;P&gt;This works irrespective of the encrypted type by looking at the $N$ prefix on the string which tell NSO what was used to encrypt. See tailf-common.yang for the&amp;nbsp; hash functions and encrypted types that are supported.&lt;/P&gt;</description>
      <pubDate>Thu, 15 Sep 2022 15:09:01 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4687958#M7385</guid>
      <dc:creator>snovello</dc:creator>
      <dc:date>2022-09-15T15:09:01Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4688481#M7387</link>
      <description>&lt;P&gt;Perfect. Thanks for sending me in that direction. The solution ended up looking like this.&lt;/P&gt;&lt;P&gt;In my YANG-file&lt;/P&gt;&lt;PRE&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;leaf&amp;nbsp;authentication-key&amp;nbsp;{&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type&amp;nbsp;tailf:aes-cfb-128-encrypted-string;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;type&amp;nbsp;string;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mandatory&amp;nbsp;true;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/PRE&gt;&lt;P&gt;and in my Python code I extract and decrypt the auth key&lt;/P&gt;&lt;PRE&gt;service_dict = ncs.maagic.as_pyval(service)&lt;BR /&gt;with ncs.maapi.Maapi() as maapi:&lt;BR /&gt;    maapi.install_crypto_keys()&lt;BR /&gt;    if service_dict["authentication_key"]:&lt;BR /&gt;        authentication_key = ncs._ncs.decrypt(service_dict["authentication_key"])&lt;BR /&gt;    else:&lt;BR /&gt;    authentication_key = None&lt;BR /&gt;template_vars = ncs.template.Variables()&lt;BR /&gt;template_vars.add("AUTHENTICATION_KEY", authentication_key)&lt;/PRE&gt;&lt;P&gt;And, in my XML template I reference that variable. And voila.&lt;/P&gt;&lt;P&gt;Only thing that bothers me a bit, is that a "commit dry-run" will actually show the clear text password in the diff and the password shows up in clear text in CDB - but in the service definition it's encrypted. It's encrypted in CDB when a sync-from is done.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 16 Sep 2022 09:09:40 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4688481#M7387</guid>
      <dc:creator>Ole Hansen</dc:creator>
      <dc:date>2022-09-16T09:09:40Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4688670#M7388</link>
      <description>&lt;P&gt;This is a very good use case for testing whether your create callback is running as part of dry run or not. Normally of course you want to be sure your code is behaving identically in both cases but this is exactly the kind of situation where you want to know the difference. The code below lets you test and you can just have a hard coded string appearing in the dry run output.&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;from ncs.maapi import CommitParams
import ncs.maagic as maagic
is_dry_run = CommitParams(maagic.get_trans(root).get_trans_params()).is_dry_run()&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 16 Sep 2022 15:27:53 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4688670#M7388</guid>
      <dc:creator>snovello</dc:creator>
      <dc:date>2022-09-16T15:27:53Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4689820#M7391</link>
      <description>&lt;P&gt;Great. That works. Now I'll just print a message instead of the authentication-key when doing a dry run.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It does, however, not solve my issue where the clear text password is stored in CDB until a sync-from is done.&lt;/P&gt;&lt;P&gt;The documentation for the Juniper NED states that:&lt;/P&gt;&lt;P&gt;&lt;EM&gt;The standard way to handle this (in netconf in general), is to do a sync-from&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;after setting clear-text values, this will get NSO back in the state where the&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;stored value in CDB will be the same as the 'hashed' device-value.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I simply cannot figure out how to do a partial-sync-from or even a full sync-from automatically when the modification is comitted. I understand, that I can't do it within the cb_create (nor the pre_/post_modification transactions, because I'll create a deadlock (see&amp;nbsp;&lt;A href="https://community.cisco.com/t5/nso-developer-hub-discussions/call-partial-sync-from-function-in-cb-create/m-p/3895272/highlight/true#M4055" target="_blank"&gt;https://community.cisco.com/t5/nso-developer-hub-discussions/call-partial-sync-from-function-in-cb-create/m-p/3895272/highlight/true#M4055&lt;/A&gt;&amp;nbsp;)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Any pointers?&lt;/P&gt;</description>
      <pubDate>Mon, 19 Sep 2022 11:49:26 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4689820#M7391</guid>
      <dc:creator>Ole Hansen</dc:creator>
      <dc:date>2022-09-19T11:49:26Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4690017#M7397</link>
      <description>&lt;P&gt;You can update after the end of the transaction using a kicker. See docs here &lt;A href="https://developer.cisco.com/docs/nso/guides/#!kicker" target="_blank"&gt;https://developer.cisco.com/docs/nso/guides/#!kicker&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;You would set the kicker to react to any changes in the authentication-keys or passwords and it would trigger an action that does the sync-from. I think it might be&amp;nbsp; possible to have an expression that tests whether the key is unencrypted to make the triggering more accurate.&lt;/P&gt;
&lt;P&gt;I think you&amp;nbsp; might have to write your own action that uses the input to figure out what device to sync. That could call a partial sync. A kicker per device might also work if you want to use the existing sync-from action without parameters&lt;/P&gt;</description>
      <pubDate>Mon, 19 Sep 2022 17:54:51 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4690017#M7397</guid>
      <dc:creator>snovello</dc:creator>
      <dc:date>2022-09-19T17:54:51Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4690718#M7398</link>
      <description>&lt;P&gt;Ah. That got down the rabbit hole of trying to pass arguments to partial-sync-from, but this is not supported as per&amp;nbsp;&lt;A href="https://community.cisco.com/t5/nso-developer-hub-discussions/how-to-kick-and-action-with-action-parameters/td-p/4110045" target="_blank" rel="noopener"&gt;https://community.cisco.com/t5/nso-developer-hub-discussions/how-to-kick-and-action-with-action-parameters/td-p/4110045&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So. My solution is. Add a "sync-authentication-key" under my service&lt;/P&gt;&lt;PRE&gt;tailf:action "sync-authentication-key" {&lt;BR /&gt;  tailf:actionpoint sync-authentication-key;&lt;BR /&gt;  input {&lt;BR /&gt;  uses kicker:action-input-params;&lt;BR /&gt;  }&lt;BR /&gt;  output {&lt;BR /&gt;  }&lt;BR /&gt;}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;P&gt;Then add a kicker for the specific instance of the service in my xml-template&lt;/P&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;&amp;lt;kickers xmlns="http://tail-f.com/ns/kicker"&amp;gt;
  &amp;lt;data-kicker&amp;gt;
  &amp;lt;id&amp;gt;foo-{/name}-sync-authentication-key&amp;lt;/id&amp;gt;
  &amp;lt;monitor&amp;gt;/devices/device[name='{/device}']/config/junos:configuration/routing-instances/instance[name='{/vrf}']/protocols/bgp/group[name='{$GROUP}']/authentication-key&amp;lt;/monitor&amp;gt;
  &amp;lt;kick-node&amp;gt;/services/{$SERVICE_NAME}[name='{/name}']&amp;lt;/kick-node&amp;gt;
  &amp;lt;action-name&amp;gt;sync-authentication-key&amp;lt;/action-name&amp;gt;
  &amp;lt;/data-kicker&amp;gt;
&amp;lt;/kickers&amp;gt;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;P&gt;And then my action-code&lt;/P&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;class SyncAuthenticationKey(Action):
    &lt;a href="https://community.cisco.com/t5/user/viewprofilepage/user-id/455588"&gt;@Action&lt;/a&gt;.action
    def cb_action(self, uinfo, name, kp, input, output, trans):
        self.log.info(f"Action SyncAuthenticationKey({kp=}")
        with ncs.maapi.Maapi() as m:
            m.start_user_session(uinfo.username, "Action_Context")
            with m.attach(uinfo.actx_thandle) as t:
                root = ncs.maagic.get_root(m)
                service = ncs.maagic.get_node(t, kp)

                partial_sync_from = root.ncs__devices.partial_sync_from
                input = partial_sync_from.get_input()

                service_name = service.name.replace("-", "_")

                input_path = f"/devices/device/[name='{service.device}']"
                input_path += f"/config/configuration/routing-instances"
                input_path += f"/instance[name='{service.vrf}']/protocols/bgp"
                input_path += f"/group[name='{service_name}']/authentication-key"

                self.log.debug(f"{input_path=}")

                input.path = [input_path]

                result = partial_sync_from(input)

                for sync_result in result.sync_result:
                    if not sync_result.result:
                        self.log.error(f"Partial sync for {service.device} failed")
                    else:
                        self.log.info(f"Partial sync for {service.device} successful")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And to answer your suggestion on checking for dry run, i ended up with&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;        dry_run = CommitParams(maagic.get_trans(root).get_trans_params()).is_dry_run()
        service_dict = ncs.maagic.as_pyval(service)

        if not dry_run:
            with ncs.maapi.Maapi() as maapi:
                # to be able to decrypt credentials, we need to install crypto keys
                maapi.install_crypto_keys()
                if service_dict["authentication_key"]:
                    self.log.debug(
                        f"Going to decrypt {service_dict['authentication_key']}"
                    )
                    authentication_key = ncs._ncs.decrypt(
                        service_dict["authentication_key"]
                    )
                else:
                    authentication_key = None
        else:
            authentication_key = "*** Authentication key is hashed - refusing to print the key in clear text ***"&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 20 Sep 2022 13:19:18 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4690718#M7398</guid>
      <dc:creator>Ole Hansen</dc:creator>
      <dc:date>2022-09-20T13:19:18Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4691111#M7401</link>
      <description>&lt;P&gt;I'll just continue my "blabbering" &lt;span class="lia-unicode-emoji" title=":winking_face:"&gt;😉&lt;/span&gt;&lt;/P&gt;&lt;P&gt;This method has one major drawback. The kicker won't be activated when creating a new service, because it happens within one transaction, so the kicker is only active on subsequent edits to the service. Instead of individual triggers, I may just have *one* trigger, that does the sync if any authentication-key is changed.&lt;/P&gt;</description>
      <pubDate>Wed, 21 Sep 2022 07:11:16 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4691111#M7401</guid>
      <dc:creator>Ole Hansen</dc:creator>
      <dc:date>2022-09-21T07:11:16Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4694089#M7423</link>
      <description>&lt;DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;I simply cannot figure out how where to call the "partial-sync-from". If I put it in post_modification it times out - probably because the transaction is not closed, hence I'm creating a deadlock.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;BR /&gt;&lt;DIV&gt;&lt;SPAN&gt;I've tried making a "generic" kicker, that monitors the authentication-key part of the configuration - but I cannot figure out how to write a path, that includes wildcards.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&lt;A href="https://developer.cisco.com/docs/nso/guides/#!developing-nso-services/partial-sync" target="_blank"&gt;https://developer.cisco.com/docs/nso/guides/#!developing-nso-services/partial-sync&lt;/A&gt;&amp;nbsp;mentions "Hence it is a good practice for such service to implement a wrapper action that invokes the generic /devices/partial-sync-from action with the correct list of paths" - but nothing about where to place it.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;Any pointers are more than welcome. I've been banging my head against this for a couple of days now &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Mon, 26 Sep 2022 19:23:40 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4694089#M7423</guid>
      <dc:creator>Ole Hansen</dc:creator>
      <dc:date>2022-09-26T19:23:40Z</dc:date>
    </item>
    <item>
      <title>Re: Storing and deploying BGP authentication keys with NSO</title>
      <link>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4695197#M7426</link>
      <description>&lt;P&gt;Hey.&lt;/P&gt;&lt;P&gt;You mentioned kicker problems (not firing because kicker and change it should fire based on are part of the same transaction). Doing partial sync in service code itself might not be ideal either. To me it seems like you need a subscriber code to address these two. Difference between kicker and subscriber in function is that subscriber runs constantly (from packages reload that starts it up) and can differentiate between operations made on nodes.&lt;/P&gt;&lt;P&gt;Not directly answering your last problem but in subscriber, depending on how you monitor, you can catch paths that are being monitored and are processed by the NSO. Out of that you can perhaps make a list of which devices you want to partial sync from and pass it to your action as arguments.&lt;/P&gt;</description>
      <pubDate>Wed, 28 Sep 2022 07:25:39 GMT</pubDate>
      <guid>https://community.cisco.com/t5/nso-developer-hub-discussions/storing-and-deploying-bgp-authentication-keys-with-nso/m-p/4695197#M7426</guid>
      <dc:creator>u.avsec</dc:creator>
      <dc:date>2022-09-28T07:25:39Z</dc:date>
    </item>
  </channel>
</rss>

