clicon / clixon-controller

Clixon network controller
Apache License 2.0
14 stars 5 forks source link

"commit diff" after applying a service always seems to show a diff #70

Closed krihal closed 9 months ago

krihal commented 10 months ago

If a service is commited without errors there should be no diff if doing "commit diff". Example:

Applying a service:

debian@khn-dev[/]# set services ssh-users test username foo ssh-key "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7$
debian@khn-dev[/]# set services ssh-users test username foo class super-user

Committing the service:

debian@khn-dev[/]# commit
OK

The commit above was successful but there are still a diff:

debian@khn-dev[/]# commit diff
juniper1:
         <login xmlns="http://yang.juniper.net/junos/conf/root">
-           <user>
-              <name>foo</name>
-              <class>super-user</class>
-              <authentication>
-                 <ssh-rsa>
-                    <name>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7bQjN59GZO6QrYCmnAcqW9GXTMq67xLcdPquSGcJlJd2evCXKRD88ZOeMYHLFcWSzJJhsFazHn7V4IEhdDxRdFo7ablaei9Em2OLQiF0QWNowLvUN+q8SMadvllVc2lL+ZWy+MnU8EGdhn++uCwv8hff5qByiY6e/r7rmaaelnXvsdHQ4dSg6FLsNCijdn7nMDo5/GDygx6bBr1c0cnr7VemxeIUbJk0CtwdZDg8MY/lzlo6AnaJA0U2kozyikw2aVjsPUEeww6S6wc74N9nEkqTt8q8uhp9QqUy3ISu79HqtUNq8F1MDZBADpEnJ9YJq32+WHtyzdwo3pTvKmWyjv3YFDo6Ghtxm4UGn4JqZa+D9JCZGl9wb3A/CJSUeCgyMhvtSXkJSAt9c+C70/2NQOO6NtLUNtfauzM4IpsVKLACWxGT395ugKqH+y5kVtXjUcAkyVeTeyX4TJghDUVxhekM/Sw+pr5CbSKwUCdt7SXbquT+5zVkeAabpNy7Zd60= root@zoomie</name>
-                 </ssh-rsa>
-              </authentication>
-           </user>
         </login>
juniper2:
         <login xmlns="http://yang.juniper.net/junos/conf/root">
-           <user>
-              <name>foo</name>
-              <class>super-user</class>
-              <authentication>
-                 <ssh-rsa>
-                    <name>ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC7bQjN59GZO6QrYCmnAcqW9GXTMq67xLcdPquSGcJlJd2evCXKRD88ZOeMYHLFcWSzJJhsFazHn7V4IEhdDxRdFo7ablaei9Em2OLQiF0QWNowLvUN+q8SMadvllVc2lL+ZWy+MnU8EGdhn++uCwv8hff5qByiY6e/r7rmaaelnXvsdHQ4dSg6FLsNCijdn7nMDo5/GDygx6bBr1c0cnr7VemxeIUbJk0CtwdZDg8MY/lzlo6AnaJA0U2kozyikw2aVjsPUEeww6S6wc74N9nEkqTt8q8uhp9QqUy3ISu79HqtUNq8F1MDZBADpEnJ9YJq32+WHtyzdwo3pTvKmWyjv3YFDo6Ghtxm4UGn4JqZa+D9JCZGl9wb3A/CJSUeCgyMhvtSXkJSAt9c+C70/2NQOO6NtLUNtfauzM4IpsVKLACWxGT395ugKqH+y5kVtXjUcAkyVeTeyX4TJghDUVxhekM/Sw+pr5CbSKwUCdt7SXbquT+5zVkeAabpNy7Zd60= root@zoomie</name>
-                 </ssh-rsa>
-              </authentication>
-           </user>
         </login>
OK
krihal commented 10 months ago

Will try to reproduce with OpenConfig.

krihal commented 10 months ago

To reproduce:

Put this under /usr/local/share/clixon/controller/main/ssh-users.yang:

module ssh-users {
    namespace "http://clicon.org/ssh-users";
    prefix ssh-users;

    import ietf-inet-types { prefix inet; }
    import clixon-controller { prefix ctrl; }

    revision 2023-05-22{
        description "Initial prototype";
    }

    augment "/ctrl:services" {
        list ssh-users {
            key service-name;

            leaf service-name {
                type string;
            }

            description "SSH users service";

            list username {
                key name;

                leaf name {
                    type string;
                }

                leaf ssh-key {
                    type string;
                }

                leaf role {
                     type string;
                }
            }
        }
    }
}

Put this under /usr/local/share/clixon/controller/modules/ssh-users.py:

from clixon.element import Element
from clixon.parser import parse_template

SERVICE = "ssh-users"

USER_XML = """
<user cl:creator="ssh-users[service-name='{{SERVICE_NAME}}']" nc:operation="merge" xmlns:cl="http://clicon.org/lib">
    <username>{{USERNAME}}</username>
    <config>
        <username>{{USERNAME}}</username>
        <ssh-key>{{SSH_KEY}}</ssh-key>
        <role>{{ROLE}}</role>
    </config>
</user>
"""

def setup(root, log, **kwargs):
    try:
        _ = root.services
    except Exception:
        return

    for instance in root.services.ssh_users:
        for user in instance.username:
            service_name = instance.service_name.cdata
            username = user.name.cdata
            ssh_key = user.ssh_key.cdata
            role = user.role.cdata

            new_user = parse_template(USER_XML, SERVICE_NAME=service_name,
                                      USERNAME=username, SSH_KEY=ssh_key, ROLE=role).user

            for device in root.devices.device:
                if device.config.system.get_elements("aaa") == []:
                    device.config.system.create("aaa")
                if device.config.system.aaa.get_elements("authentication") == []:
                    device.config.system.aaa.create("authentication")
                if device.config.system.aaa.authentication.get_elements("users") == []:
                    device.config.system.aaa.authentication.create("users")
                device.config.system.aaa.authentication.users.add(new_user)

Start the backend and connect to one or more OpenConfig devices. Then configure the service:

# set services ssh-users test username test
# set services ssh-users test username test role test
# set services ssh-users test username test ssh-key test

Commit the service:

# commit

And now do a "commit diff":

debian@khn-dev[/]# commit diff
openconfig1:
   <system xmlns="http://openconfig.net/yang/system">
-     <aaa>
-        <authentication>
-           <users>
-              <user>
-                 <username>test</username>
-                 <config>
-                    <username>test</username>
-                    <ssh-key>test</ssh-key>
-                    <role>test</role>
-                 </config>
-              </user>
-           </users>
-        </authentication>
-     </aaa>
   </system>
openconfig2:
   <system xmlns="http://openconfig.net/yang/system">
-     <aaa>
-        <authentication>
-           <users>
-              <user>
-                 <username>test</username>
-                 <config>
-                    <username>test</username>
-                    <ssh-key>test</ssh-key>
-                    <role>test</role>
-                 </config>
-              </user>
-           </users>
-        </authentication>
-     </aaa>
   </system>
OK
krihal commented 9 months ago

commit_diff.txt commit.txt

krihal commented 9 months ago

Verified.