syntax = "proto3";

package pbservice;

option go_package = "github.com/hashicorp/consul/proto/pbservice";

import "google/protobuf/struct.proto";
import "proto/pbcommon/common.proto";
import "proto/pbservice/healthcheck.proto";

// This fake import path is replaced by the build script with a versioned path
import "gogoproto/gogo.proto";

option (gogoproto.goproto_unkeyed_all) = false;
option (gogoproto.goproto_unrecognized_all) = false;
option (gogoproto.goproto_getters_all) = false;
option (gogoproto.goproto_sizecache_all) = false;


// ConnectProxyConfig describes the configuration needed for any proxy managed
// or unmanaged. It describes a single logical service's listener and optionally
// upstreams and sidecar-related config for a single instance. To describe a
// centralized proxy that routed traffic for multiple services, a different one
// of these would be needed for each, sharing the same LogicalProxyID.
//
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.ConnectProxyConfig
// output=service.gen.go
// name=Structs
message ConnectProxyConfig {
    // DestinationServiceName is required and is the name of the service to accept
    // traffic for.
    string DestinationServiceName = 1;

    // DestinationServiceID is optional and should only be specified for
    // "side-car" style proxies where the proxy is in front of just a single
    // instance of the service. It should be set to the service ID of the instance
    // being represented which must be registered to the same agent. It's valid to
    // provide a service ID that does not yet exist to avoid timing issues when
    // bootstrapping a service with a proxy.
    string DestinationServiceID = 2;

    // LocalServiceAddress is the address of the local service instance. It is
    // optional and should only be specified for "side-car" style proxies. It will
    // default to 127.0.0.1 if the proxy is a "side-car" (DestinationServiceID is
    // set) but otherwise will be ignored.
    string LocalServiceAddress = 3;

    // LocalServicePort is the port of the local service instance. It is optional
    // and should only be specified for "side-car" style proxies. It will default
    // to the registered port for the instance if the proxy is a "side-car"
    // (DestinationServiceID is set) but otherwise will be ignored.
    // mog: func-to=int func-from=int32
    int32 LocalServicePort = 4;

    // Config is the arbitrary configuration data provided with the proxy
    // registration.
    // mog: func-to=ProtobufTypesStructToMapStringInterface func-from=MapStringInterfaceToProtobufTypesStruct
    google.protobuf.Struct Config = 5 [(gogoproto.nullable) = true];

    // Upstreams describes any upstream dependencies the proxy instance should
    // setup.
    // mog: func-to=UpstreamsToStructs func-from=NewUpstreamsFromStructs
    repeated Upstream Upstreams = 6 [(gogoproto.nullable) = false];

    // MeshGateway defines the mesh gateway configuration for this upstream
    MeshGatewayConfig MeshGateway = 7 [(gogoproto.nullable) = false];

    // Expose defines whether checks or paths are exposed through the proxy
    ExposeConfig Expose = 8 [(gogoproto.nullable) = false];
}

// Upstream represents a single upstream dependency for a service or proxy. It
// describes the mechanism used to discover instances to communicate with (the
// Target) as well as any potential client configuration that may be useful such
// as load balancer options, timeouts etc.
//
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.Upstream
// output=service.gen.go
// name=Structs
// ignore-fields=IngressHosts
message Upstream {
    // Destination fields are the required ones for determining what this upstream
    // points to. Depending on DestinationType some other fields below might
    // further restrict the set of instances allowable.
    //
    // DestinationType would be better as an int constant but even with custom
    // JSON marshallers it causes havoc with all the mapstructure mangling we do
    // on service definitions in various places.
    string DestinationType = 1;
    string DestinationNamespace = 2;
    string DestinationName = 3;

    // Datacenter that the service discovery request should be run against. Note
    // for prepared queries, the actual results might be from a different
    // datacenter.
    string Datacenter = 4;

    // LocalBindAddress is the ip address a side-car proxy should listen on for
    // traffic destined for this upstream service. Default if empty is 127.0.0.1.
    string LocalBindAddress = 5;

    // LocalBindPort is the ip address a side-car proxy should listen on for
    // traffic destined for this upstream service. Required.
    // mog: func-to=int func-from=int32
    int32 LocalBindPort = 6;

    // Config is an opaque config that is specific to the proxy process being run.
    // It can be used to pass arbitrary configuration for this specific upstream
    // to the proxy.
    // mog: func-to=ProtobufTypesStructToMapStringInterface func-from=MapStringInterfaceToProtobufTypesStruct
    google.protobuf.Struct Config = 7 [(gogoproto.nullable) = true];

    // MeshGateway is the configuration for mesh gateway usage of this upstream
    MeshGatewayConfig MeshGateway = 8  [(gogoproto.nullable) = false];
}

// ServiceConnect are the shared Connect settings between all service
// definitions from the agent to the state store.
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.ServiceConnect
// output=service.gen.go
// name=Structs
message ServiceConnect {
    // Native is true when this service can natively understand Connect.
    bool Native = 1;

    // SidecarService is a nested Service Definition to register at the same time.
    // It's purely a convenience mechanism to allow specifying a sidecar service
    // along with the application service definition. It's nested nature allows
    // all of the fields to be defaulted which can reduce the amount of
    // boilerplate needed to register a sidecar service separately, but the end
    // result is identical to just making a second service registration via any
    // other means.
    // mog: func-to=ServiceDefinitionPtrToStructs func-from=NewServiceDefinitionPtrFromStructs
    ServiceDefinition SidecarService = 3;
}

// ExposeConfig describes HTTP paths to expose through Envoy outside of Connect.
// Users can expose individual paths and/or all HTTP/GRPC paths for checks.
//
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.ExposeConfig
// output=service.gen.go
// name=Structs
message ExposeConfig {
    // Checks defines whether paths associated with Consul checks will be exposed.
    // This flag triggers exposing all HTTP and GRPC check paths registered for the service.
    bool Checks = 1;

    // Paths is the list of paths exposed through the proxy.
    // mog: func-to=ExposePathSliceToStructs func-from=NewExposePathSliceFromStructs
    repeated ExposePath Paths = 2 [(gogoproto.nullable) = false];
}

// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.ExposePath
// output=service.gen.go
// name=Structs
message ExposePath {
    // ListenerPort defines the port of the proxy's listener for exposed paths.
    // mog: func-to=int func-from=int32
    int32 ListenerPort = 1;

    // ExposePath is the path to expose through the proxy, ie. "/metrics."
    string Path = 2;

    // LocalPathPort is the port that the service is listening on for the given path.
    // mog: func-to=int func-from=int32
    int32 LocalPathPort = 3;

    // Protocol describes the upstream's service protocol.
    // Valid values are "http" and "http2", defaults to "http"
    string Protocol = 4;

    // ParsedFromCheck is set if this path was parsed from a registered check
    bool ParsedFromCheck = 5;
}

// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.MeshGatewayConfig
// output=service.gen.go
// name=Structs
message MeshGatewayConfig {
    string Mode = 1 [(gogoproto.casttype) = "github.com/hashicorp/consul/agent/structs.MeshGatewayMode"];
}

// ServiceDefinition is used to JSON decode the Service definitions. For
// documentation on specific fields see NodeService which is better documented.
//
// mog annotation:
//
// target=github.com/hashicorp/consul/agent/structs.ServiceDefinition
// output=service.gen.go
// name=Structs
message ServiceDefinition {
    string Kind = 1 [(gogoproto.casttype) = "github.com/hashicorp/consul/agent/structs.ServiceKind"];
    string ID = 2;
    string Name = 3;
    repeated string Tags = 4;
    string Address = 5;
    // mog: func-to=MapStringServiceAddressToStructs func-from=NewMapStringServiceAddressFromStructs
    map<string, ServiceAddress> TaggedAddresses = 16 [(gogoproto.nullable) = false];
    map<string, string> Meta = 6;
    // mog: func-to=int func-from=int32
    int32 Port = 7;
    CheckType Check = 8 [(gogoproto.nullable) = false];
    // mog: func-to=CheckTypesToStructs func-from=NewCheckTypesFromStructs
    repeated CheckType Checks = 9;
    // mog: func-to=WeightsPtrToStructs func-from=NewWeightsPtrFromStructs
    Weights Weights = 10;
    string Token = 11;
    bool EnableTagOverride = 12;

    // Proxy is the configuration set for Kind = connect-proxy. It is mandatory in
    // that case and an error to be set for any other kind. This config is part of
    // a proxy service definition and is distinct from but shares some fields with
    // the Connect.Proxy which configures a managed proxy as part of the actual
    // service's definition. This duplication is ugly but seemed better than the
    // alternative which was to re-use the same struct fields for both cases even
    // though the semantics are different and the non-shared fields make no sense
    // in the other case. ProxyConfig may be a more natural name here, but it's
    // confusing for the UX because one of the fields in ConnectProxyConfig is
    // also called just "Config"
    // mog: func-to=ConnectProxyConfigPtrToStructs func-from=NewConnectProxyConfigPtrFromStructs
    ConnectProxyConfig Proxy = 14;

    // mog: func-to=EnterpriseMetaToStructs func-from=NewEnterpriseMetaFromStructs
    common.EnterpriseMeta EnterpriseMeta = 17 [(gogoproto.nullable) = false];

    // mog: func-to=ServiceConnectPtrToStructs func-from=NewServiceConnectPtrFromStructs
    ServiceConnect Connect = 15;
}

// Type to hold an address and port of a service
message ServiceAddress {
    string Address = 1;
    // mog: func-to=int func-from=int32
    int32 Port = 2;
}


// Weights represent the weight used by DNS for a given status
message Weights {
    // mog: func-to=int func-from=int32
    int32 Passing = 1;
    // mog: func-to=int func-from=int32
    int32 Warning = 2;
}