module openconfig-system-grpc {
  yang-version "1";

  namespace "http://openconfig.net/yang/system-grpc";
  prefix "oc-sys-grpc";

  import openconfig-extensions { prefix oc-ext; }
  import openconfig-system { prefix oc-sys; }
  import openconfig-inet-types { prefix oc-inet; }
  import openconfig-network-instance { prefix oc-ni; }

  organization
    "OpenConfig working group";
  contact
    "www.openconfig.net";

  description
    "This module adds configuration and operational state relating to gRPC
    services running on a network device. The GRPC_SERVICE identity is used
    to create an extensible list of services that can be instantiated, with
    a base set defined in this module. New services can extend the identity
    to be included in the list.";


  oc-ext:openconfig-version "0.1.1";
  oc-ext:catalog-organization "openconfig";
  oc-ext:origin "openconfig";

  revision "2021-06-16" {
    description
      "Remove trailing whitespace";
    reference "0.1.1";
  }

  revision 2021-03-30 {
    description
      "Initial revision.";
    reference "0.1.0";
  }

  identity GRPC_SERVICE {
    description
      "Base identity for a gRPC-based service.";
  }

  identity GNMI {
    base GRPC_SERVICE;
    description
      "gNMI: gRPC Network Management Interface";
  }

  grouping grpc-service-structural {
    description
      "Structural grouping for gRPC services that can be enabled on
      the system.";

    container grpc-servers {
      description
        "List of gRPC servers that can be configured on the device.";

      list grpc-server {
        key "name";

        description
          "The list of gRPC servers that are running on the device. Each
          instance within this list corresponds to an individual gRPC listener
          that listens on a single TCP port on the specified addresses.
          Where there are multiple services that run on a single port, these
          are enabled through the service leaf-list which uses the GRPC_SERVICE
          identity to list the supported service types.";

        leaf name {
          type leafref {
            path "../config/name";
          }
          description
            "Reference to the name of the service that is to be enabled.";
        }

        container config {
          description
            "Configuration parameters relating to the gRPC service.";

          uses grpc-server-config;
          }

        container state {
          config false;
          description
            "Operational state relating to the gRPC service.";
          uses grpc-server-config;
        }
      }
    }
  }

  grouping grpc-server-config {
    description
      "Configuration parameters corresponding to an individual gRPC
      server.";

    leaf name {
      type string;
      description
        "The name of the gRPC server instance that is running on
        the local system.";
    }

    leaf-list services {
      type identityref {
        base GRPC_SERVICE;
      }
      description
        "The gRPC service definitions that should be enabled for the
        specified server. A target may support only specific
        sets of services being enabled on the same server (e.g.,
        it may be possible to run gNMI and gNOI services on the same
        port, but not to run gRIBI and gNMI on the same port).

        The set of gRPC services that are available to be configured is
        defined through the GRPC_SERVICE identity, which can be extended
        for each protocol that is based on gRPC that is available on the
        device.";
    }

    leaf enable {
      type boolean;
      description
        "When set to true, the gRPC server is enabled and runs on the
        local device.";
    }

    leaf port {
      type oc-inet:port-number;
      description
        "TCP port on which the gRPC server should listen.";
    }

    leaf transport-security {
      type boolean;
      default true;
      description
        "Use gRPC transport security (e.g., SSL or TLS). Enabled by default.
        This leaf allows transport security to be disabled for use cases that
        are not supported, such as lab testing.";
    }

    leaf certificate-id {
      type string;
      description
        "Name of the certificate that is associated with the gRPC service. The
        certificate ID is provisioned through other interfaces to the device, such
        as the gNOI certificate management service.";
    }

    leaf metadata-authentication {
      type boolean;
      description
        "When set to true, metadata authentication is enabled for the gRPC server.
        In this mode of operation, gRPC metadata is used to carry authentication
        credentials as per the specification in
        https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-authentication.md#credentials-and-authentication.";
    }

    leaf-list listen-addresses {
      type union {
        type oc-inet:ip-address;
        type enumeration {
          enum ANY {
            description
              "The gRPC server should listen on any address bound to an interface
              of the system.";
          }
        }
      }
      description
        "The IP addresses that the gRPC server should listen on. This may be
        an IPv4 or an IPv6 address (or both).";
    }

    leaf network-instance {
      type oc-ni:network-instance-ref;
      description
        "The network instance within which the gRPC server is listening.
        When unspecified, the DEFAULT_INSTANCE should be used.";
    }
  }

  augment "/oc-sys:system" {
    description
      "Add gRPC service configuration to the openconfig-system model.";

    uses grpc-service-structural;
  }
}
