module yumaworks-yp-ha {

    namespace "http://yumaworks.com/ns/yumaworks-yp-ha";

    prefix "yph";

    import ietf-yang-structure-ext { prefix sx; }
    import ietf-yang-types { prefix yang; }
    import yuma-ncx { prefix ncx; }
    import yumaworks-ycontrol { prefix yctl; }
    import ietf-yang-patch { prefix ypatch; }

    organization "YumaWorks, Inc.";

    contact
        "Support <support at yumaworks.com>";

    description
       "YumaPro High Availability message definitions.

     Copyright (c) 2016 - 2023, YumaWorks, Inc. All rights reserved.

     Redistribution and use in source and binary forms, with or
     without modification, is permitted pursuant to, and subject
     to the license terms contained in, the BSD 3-Clause License
     http://opensource.org/licenses/BSD-3-Clause";

    revision 2023-08-04 {
      description
        "22.10T-11: Change CLI container to sx:structure";
    }

    revision 2017-09-19 {
        description
          "Fix broken augment statement for payload";
    }

    revision 2016-08-16 {
        description
          "16.10-B3 release";
    }

    revision 2016-07-10 {
        description
          "16.10-B2 release";
    }

    revision 2016-02-06 {
        description
          "First release";
    }

    sx:augment-structure
      "/yctl:ycontrol/yctl:message-payload/yctl:payload/yctl:payload" {
      container yp-ha {

        description
          "YumaPro High Availability API Messages

           Server Role == HA Active Server
           Subsys Role == HA Standby Server

           YP-HA Protocol Initialization:

           Active Server Initialization:
             1) server starts listening for YControl connections
             2) YP-HA service listens for yp-ha messages

           Standby Server Connect:
             1) subsys starts YControl session to server
             2) subsys sends <register-request>
             3) server sends <ok> or <error>

           Config Update:
             1) server sends <config-update> event
             3) subsys sends <upate-failed> event only to NACK

           Events:
             A) server sends <nvstore> event to support :startup
             B) server sends <module-update> if module set changes
           ";

        choice message-type {
          mandatory true;

          container register-request {
            description
             "Message type: subsys-request;
              Purpose: register the YP-HA standby server with
              the active server. The <subsys-id> field is
              used as the server-id and must match a server name
              configured in the ha-server list on the active server.
              Expected Response Message: ok or error";

            leaf server-key {
              type string;
              mandatory true;
              description
               "Server pool key string configured for this server pool.
                Must match the value expected by the active server
                or the active server will reject the registration
                request.";
            }
            leaf config-id {
              type uint64;
              description
                "The running configuration ID string that the
                 standby server thinks is the current config-id
                 for the server pool.  If not present then the
                 standby server does not have a running config
                 and is requesting a full copy of the running config.";
            }
            leaf config-stamp {
              type yang:date-and-time;
              description
                "The running last-changed timestamp that the
                 standby server thinks is for the current config-id
                 for the server pool. This timestamp is optional.";
            }
          }

          container config-update {
            description
             "Message type: server-event;
              Purpose: The active server is sending
              a configuration load or update for the
              running datastore.

              This message contains either a <config> complete subtree
              or a YANG Patch where the Target Resource URI is
              hard-wired to the datastore root.

              Expected Response Message: none; Standby server will
              send an update-failed event if the config was not
              accepted for any reason.";

            leaf last-config-id {
              type uint64;
              description
                "The config-id ETag of the datastore before this edit
                 was applied. If none because this is a load-config,
                 then this leaf will not be present.";
            }

            leaf cur-config-id {
              mandatory true;
              type uint64;
              description
                "The config-id ETag of the datastore after this edit
                 was applied.";
            }

            leaf cur-config-stamp {
              mandatory true;
              type yang:date-and-time;
              description
                "The config-id Last-Modified timestamp value after
                 this edit was applied.";
            }

            leaf nvstore {
              type empty;
              description
                "This config update needs to be NV-stored.
                 Do not NV-store unless this empty leaf is present.";
            }

            choice config-type {
              container config {
                ncx:root;
                ncx:metadata "string last-modified";
                ncx:metadata "string etag";
                description
                   "The active server is sending a complete configuration
                    to the standby server, not a patch update. Sent if the
                    register-request from the standby server did not contain
                    config-id and config-stamp objects.";
              }
              case config-patch {
                uses ypatch:yang-patch;
              }
            }

          }  // container config-update

          leaf nvstore {
            type empty;
            description
             "Message type: server-event;
              Purpose: The active server has been told to save the
              :startup configuration to non-volatile storage.
              Expected Response: none";
          }

          container module-update {
            description
             "Message type: server-event;
              Purpose: The module set has been updated on the
              active server.
              Expected Response: none";

            leaf event-type {
              type enumeration {
                enum load;
                enum load-bundle;
                enum unload;
                enum unload-bundle;
              }
              mandatory true;
              description
                "Dynamic change to module set.";
            }
            leaf name {
              type string;
              mandatory true;
              description "Module or bundle name";
            }
            leaf revision {
              type string;
              description "Module or bundle revision date";
            }
            // dynamic feature config not supported yet
            leaf-list deviation {
              type string;
              description
                "Deviation module for load or load-bundle";
            }
          }

          container update-failed {
            description
             "Message type: subsys-event;
              Purpose: The config-update failed
              Expected Response: none";

            leaf config-id {
              type uint64;
              description
                "The config-id of the rejected update.";
            }
          }

        } // choice message-type
      } // container yp-ha
    } // augment
}
