module clixon-restconf {
    yang-version 1.1;
    namespace "http://clicon.org/restconf";
    prefix "clrc";

    import ietf-inet-types {
        prefix inet;
    }

    organization
        "Clixon";

    contact
        "Olof Hagsand <olof@hagsand.se>";

    description
        "This YANG module provides a data-model for the Clixon RESTCONF daemon.
         There is also clixon-config also including some restconf options.
         The separation is not always logical but there are some reasons for the split:
         1. Some data (ie 'socket') is structurally complex and cannot be expressed as a 
            simple option
         2. clixon-restconf is defined as a macro/grouping and can be included in
            other YANGs. In particular, it can be used inside a datastore, which
            is not possible for clixon-config.
         3. Related to (2), options that should not be settable in a datastore should be
            in clixon-config

       Some of this spec if in-lined from ietf-restconf-server@2022-05-24.yang 
       ";
    revision 2022-08-01 {
        description
            "Added socket/call-home container
             Released in Clixon 5.9";
    }
    revision 2022-03-21 {
        description
            "Added feature:
                    http-data - Limited static http server
             Released in Clixon 5.7";
    }
    revision 2021-05-20 {
        description
            "Added log-destination for restconf
             Released in Clixon 5.2";
    }
    revision 2021-03-15 {
        description
            "make authentication-type none a feature
             Added flag to enable core dumps
             Released in Clixon 5.1";
    }
    revision 2020-12-30 {
        description
            "Added: debug field
             Added 'none' as default value for auth-type
             Changed http-auth-type enum from 'password' to 'user'";
    }
    revision 2020-10-30 {
        description
            "Initial release";
    }
    feature fcgi {
        description
            "This feature indicates that the restconf server supports the fast-cgi reverse
             proxy solution.
             That is, a reverse proxy is the HTTP front-end and the restconf daemon listens
             to a fcgi socket.
             The alternative is the internal native HTTP solution.";
    }

    feature allow-auth-none {
        description
          "This feature allows the use of authentication-type none.";
    }

    feature http-data {
        description
            "This feature allows for a very limited static http-data function as
             addition to RESTCONF.
             It is limited to:
             1. path: Local static files within WWW_DATA_ROOT
             2. operation GET, HEAD, OPTIONS
             3. query parameters not supported
             4. indata should be NULL (no write operations)
             5. Limited media: text/html, JavaScript, image, and css
             6. Authentication as restconf
             7. HTTP/1+2, TLS as restconf";
    }
    typedef http-auth-type {
        type enumeration {
            enum none {
                if-feature "allow-auth-none";
                description
                    "Incoming message are set to authenticated by default. No ca-auth callback is called,
                     Authenticated user is set to special user 'none'.
                     Typically assumes NACM is not enabled.";
            }
            enum client-certificate {
                description
                    "TLS client certificate validation is made on each incoming message. If it passes
                    the authenticated user is extracted from the SSL_CN parameter
                     The ca-auth callback can be used to revise this behavior.";
            }
            enum user {
                description
                    "User-defined authentication as defined by the ca-auth callback.
                     One example is some form of password authentication, such as basic auth.";
            }
        }
        description
            "Enumeration of HTTP authorization types.";
    }
    typedef log-destination {
        type enumeration {
            enum syslog {
                description
                "Log to syslog with:
                    ident: clixon_restconf and PID
                    facility: LOG_USER";
            }
            enum file {
                description
                "Log to generated file at /var/log/clixon_restconf.log";
            }
        }
    }
    grouping clixon-restconf{
        description
            "HTTP RESTCONF configuration.";
        leaf enable {
            type boolean;
            default "false";
            description
                "Enables RESTCONF functionality.
                 Note that starting/stopping of a restconf daemon is different from it being
                 enabled or not.
                 For example, if the restconf daemon is under systemd management, the restconf
                 daemon will only start if enable=true.";
        }
        leaf enable-http-data {
            type boolean;
            default "false";
            if-feature "http-data";
            description
                "Enables Limited static http-data functionality.
                 enable must be true for this option to be meaningful.";
        }
        leaf auth-type {
            type http-auth-type;
            description
                "The authentication type.
                 Note client-certificate applies only if ssl-enable is true and socket has ssl";
            default user;
        }
        leaf debug {
            description
                "Set debug level of restconf daemon.
                 0 is no debug, 1 is debugging, more is detailed debug.
                 Debug logs will be directed to log-destination with LOG_DEBUG level (for syslog)";
            type uint32;
            default 0;
        }
        leaf log-destination {
            description
                "Log destination. 
                 If debug is not set, only notice, error and warning will be logged";
            type log-destination;
            default syslog;
        }
        leaf enable-core-dump {
            description
                "enable core dumps.
                 this is a no-op on systems that don't support it.";
            type boolean;
            default false;
        }
        leaf pretty {
            type boolean;
            default true;
            description
                "Restconf return value pretty print.
                 Restconf clients may add HTTP header:
                      Accept: application/yang-data+json, or
                      Accept: application/yang-data+xml
                 to get return value in XML or JSON.
                 RFC 8040 examples print XML and JSON in pretty-printed form.
                 Setting this value to false makes restconf return not pretty-printed
                 which may be desirable for performance or tests
                 This replaces the CLICON_RESTCONF_PRETTY option in clixon-config.yang";
        }
        /* From this point only specific options
         * First fcgi-specific options
         */
        leaf fcgi-socket {
            if-feature fcgi; /* Set by default by fcgi clixon_restconf daemon */
            type string;
            default "/www-data/fastcgi_restconf.sock";
            description
                "Path to FastCGI unix socket. Should be specified in webserver
                 Eg in nginx: fastcgi_pass unix:/www-data/clicon_restconf.sock
                 Only if with-restconf=fcgi, NOT native
                 This replaces CLICON_RESTCONF_PATH option in clixon-config.yang";
        }
        /* Second, local native options */
        leaf server-cert-path {
            type string;
            description
                "Path to server certificate file.
                 Note only applies if socket has ssl enabled";
        }
        leaf server-key-path {
            type string;
            description
                "Path to server key file
                 Note only applies if socket has ssl enabled";
        }
        leaf server-ca-cert-path {
            type string;
            description
                "Path to server CA cert file
                 Note only applies if socket has ssl enabled";
        }
        list socket {
            description
                "List of server sockets that the restconf daemon listens to.
                 Not fcgi";
            key "namespace address port";
            leaf namespace {
                type string;
                description
                    "Network namespace.
                     On platforms where namespaces are not suppported, 'default'
                     Default value can be changed by RESTCONF_NETNS_DEFAULT";
            }
            leaf description{
                type string;
            }
            leaf address {
                type inet:ip-address;
                description "IP address to bind to";
            }
            leaf port {
                type inet:port-number;
                description "TCP port to bind to";
            }
            leaf ssl {
                type boolean;
                default true;
                description "Enable for HTTPS otherwise HTTP protocol";
            }
            /* Some of this in-lined from ietf-restconf-server@2022-05-24.yang */
            container call-home {
                presence
                    "Identifies that the server has been configured to initiate
                     call home connections. 
                     If set, address/port refers to destination.";
                description
                    "See RFC 8071 NETCONF Call Home and RESTCONF Call Home";
                container connection-type {
                    description
                        "Indicates the RESTCONF server's preference for how the
                         RESTCONF connection is maintained.";
                    choice connection-type {
                        mandatory true;
                        description
                            "Selects between available connection types.";
                        case persistent-connection {
                            container persistent {
                                presence
                                    "Indicates that a persistent connection is to be
                                     maintained.";
                            }
                        }
                        case periodic-connection {
                            container periodic {
                                presence
                                    "Indicates periodic connects";
                                leaf period {
                                    type uint32;     /* XXX: note uit16 in std */
                                    units "seconds"; /* XXX: note minutes in draft */
                                    default "3600";  /* XXX: same: 60min in draft */
                                    description
                                        "Duration of time between periodic connections.";
                                }
                                leaf idle-timeout {
                                    type uint16;
                                    units "seconds";
                                    default "120"; // two minutes
                                    description
                                        "Specifies the maximum number of seconds that
                                         the underlying TCP session may remain idle.
                                         A TCP session will be dropped if it is idle
                                         for an interval longer than this number of
                                         seconds.  If set to zero, then the server
                                         will never drop a session because it is idle.";
                                }
                            }
                        }
                    }
                }
                container reconnect-strategy {
                    leaf max-attempts {
                        type uint8 {
                            range "1..max";
                        }
                        default "3";
                        description
                            "Specifies the number times the RESTCONF server tries
                             to connect to a specific endpoint before moving on to
                             the next endpoint in the list (round robin).";
                    }
                }
            }
        }
    }
    container restconf {
        description
            "This presence is strictly not necessary since the enable flag
             in clixon-restconf is the flag bearing the actual semantics.
             However, removing the presence leads to default config in all
             clixon installations, even those which do not use backend-started restconf.
             One could see this as mostly cosmetically annoying.
             Alternative would be to make the inclusion of this yang conditional.";
        presence "Enables RESTCONF";
        uses clixon-restconf;
    }
}
