Feat: add external scaler (#39)

* Feat: add external scaler

Signed-off-by: ChrisLiu <chrisliu1995@163.com>

* Add docs for autoscaling

Signed-off-by: ChrisLiu <chrisliu1995@163.com>

---------

Signed-off-by: ChrisLiu <chrisliu1995@163.com>
This commit is contained in:
ChrisLiu 2023-04-26 15:47:42 +08:00 committed by GitHub
parent 1cb53dea1b
commit 7c072bc48e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1212 additions and 1 deletions

View File

@ -24,6 +24,8 @@ bases:
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
# - ../prometheus
- ../scaler
patchesStrategicMerge:
# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics

View File

@ -0,0 +1,2 @@
resources:
- service.yaml

View File

@ -0,0 +1,12 @@
---
apiVersion: v1
kind: Service
metadata:
name: external-scaler
namespace: kruise-game-system
spec:
ports:
- port: 6000
targetPort: 6000
selector:
control-plane: controller-manager

View File

@ -0,0 +1,99 @@
## Feature overview
Compared to stateless service types, game servers have higher requirements for automatic scaling, especially in terms of scaling down.
The differences between game servers become more and more obvious over time, and the precision requirements for scaling down are extremely high. Coarse-grained scaling mechanisms can easily cause negative effects such as player disconnections, resulting in huge losses for the business.
The horizontal scaling mechanism in native Kubernetes is shown in the following figure:
![autoscaling-k8s-en.png](../../images/autoscaling-k8s-en.png)
In the game scenario, its main problems are:
- At the pod level, it is unable to perceive the game server game status and therefore cannot set deletion priority based on game status.
- At the workload level, it cannot select scaling-down objects based on game status.
- At the autoscaler level, it cannot accurately calculate the appropriate number of replicas based on the game server game status.
In this way, the automatic scaling mechanism based on native Kubernetes will cause two major problems in the game scenario:
- The number of scaling down is not accurate. It is easy to delete too many or too few game servers.
- The scaling-down object is not accurate. It is easy to delete game servers with high game load levels.
The automatic scaling mechanism of OKG is shown in the following figure:
![autoscaling-okg-en.png](../../images/autoscaling-okg-en.png)
- At the game server level, each game server can report its own status and expose whether it is in the WaitToBeDeleted state through custom service quality or external components.
- At the workload level, the GameServerSet can determine the scaling-down object based on the business status reported by the game server. As described in Game Server Horizontal Scaling, the game server in the WaitToBeDeleted state is the highest priority game server to be deleted during scaling down.
- At the autoscaler level, accurately calculate the number of game servers in the WaitToBeDeleted state, and use it as the scaling-down quantity to avoid accidental deletion.
In this way, OKG's automatic scaler will only delete game servers in the WaitToBeDeleted state during the scaling-down window, achieving targeted and precise scaling down.
## Usage Example
_**Prerequisites: Install [KEDA](https://keda.sh/docs/2.10/deploy/) in the cluster.**_
Deploy the ScaledObject object to set the automatic scaling strategy. Refer to the [ScaledObject API](https://github.com/kedacore/keda/blob/main/apis/keda/v1alpha1/scaledobject_types.go) for the specific field meanings.
```yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: minecraft # Fill in the name of the corresponding GameServerSet
spec:
scaleTargetRef:
name: minecraft # Fill in the name of the corresponding GameServerSet
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
pollingInterval: 30
minReplicaCount: 0
advanced:
horizontalPodAutoscalerConfig:
behavior: # Inherit from HPA behavior, refer to https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale/#configurable-scaling-behavior
scaleDown:
stabilizationWindowSeconds: 45 # Set the scaling-down stabilization window time to 45 seconds
policies:
- type: Percent
value: 100
periodSeconds: 15
triggers:
- type: external
metricType: Value
metadata:
scalerAddress: kruise-game-external-scaler.kruise-game-system:6000
```
After deployment, change the opsState of the gs minecraft-0 to WaitToBeDeleted (see [Custom Service Quality](service_qualities.md) for automated setting of game server status).
```bash
kubectl edit gs minecraft-0
...
spec:
deletionPriority: 0
opsState: WaitToBeDeleted # Set to None initially, and change it to WaitToBeDeleted
updatePriority: 0
...
```
After the scaling-down window period, the game server minecraft-0 is automatically deleted.
```bash
kubectl get gs
NAME STATE OPSSTATE DP UP
minecraft-0 Deleting WaitToBeDeleted 0 0
minecraft-1 Ready None 0 0
minecraft-2 Ready None 0 0
# After a while
...
kubectl get gs
NAME STATE OPSSTATE DP UP
minecraft-1 Ready None 0 0
minecraft-2 Ready None 0 0
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1024 KiB

View File

@ -0,0 +1,94 @@
## 功能概览
游戏服与无状态业务类型不同,对于自动伸缩特性有着更高的要求,其要求主要体现在缩容方面。
由于游戏为强有状态业务,随着时间的推移,游戏服之间的差异性愈加明显,缩容的精确度要求极高,粗糙的缩容机制容易造成玩家断线等负面影响,给业务造成巨大损失。
原生Kubernetes中的水平伸缩机制如下图所示
![autoscaling-k8s.png](../../images/autoscaling-k8s.png)
在游戏场景下,它的主要问题在于:
- 在pod层面无法感知游戏服业务状态进而无法通过业务状态设置删除优先级
- 在workload层面无法根据业务状态选择缩容对象
- 在autoscaler层面无法定向感知游戏服业务状态计算合适的副本数目
这样一来基于原生Kubernetes的自动伸缩机制将在游戏场景下造成两大问题
- 缩容数目不精确。容易删除过多或过少的游戏服。
- 缩容对象不精确。容易删除业务负载水平高的游戏服。
OKG 的自动伸缩机制如下所示
![autoscaling-okg.png](../../images/autoscaling-okg.png)
- 在游戏服层面每个游戏服可以上报自身状态通过自定义服务质量或外部组件来暴露自身是否为WaitToBeDeleted状态。
- 在workload层面GameServerSet可根据游戏服上报的业务状态来决定缩容的对象如[游戏服水平伸缩](../快速开始/游戏服水平伸缩.md)中所述WaitToBeDeleted的游戏服是删除优先级最高的游戏服缩容时最优先删除。
- 在autoscaler层面精准计算WaitToBeDeleted的游戏服个数将其作为缩容数量不会造成误删的情况。
如此一来OKG的自动伸缩器在缩容窗口期内只会删除处于WaitToBeDeleted状态的游戏服真正做到定向缩容、精准缩容。
## 使用示例
_**前置条件:在集群中安装 [KEDA](https://keda.sh/docs/2.10/deploy/)**_
部署ScaledObject对象来设置自动伸缩策略具体字段含义可参考 [ScaledObject API](https://github.com/kedacore/keda/blob/main/apis/keda/v1alpha1/scaledobject_types.go)
```yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: minecraft #填写对应GameServerSet的名称
spec:
scaleTargetRef:
name: minecraft #填写对应GameServerSet的名称
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
pollingInterval: 30
minReplicaCount: 0
advanced:
horizontalPodAutoscalerConfig:
behavior: #继承HPA策略,可参考文档 https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale/#configurable-scaling-behavior
scaleDown:
stabilizationWindowSeconds: 45 #设置缩容稳定窗口时间为45秒
policies:
- type: Percent
value: 100
periodSeconds: 15
triggers:
- type: external
metricType: Value
metadata:
scalerAddress: kruise-game-external-scaler.kruise-game-system:6000
```
部署完成后更改gs minecraft-0 的 opsState 为 WaitToBeDeleted可参考[自定义服务质量](自定义服务质量.md)实现自动化设置游戏服状态)
```bash
kubectl edit gs minecraft-0
...
spec:
deletionPriority: 0
opsState: WaitToBeDeleted #初始为None, 将其改为WaitToBeDeleted
updatePriority: 0
...
```
经过缩容窗口期后游戏服minecraft-0自动被删除
```bash
kubectl get gs
NAME STATE OPSSTATE DP UP
minecraft-0 Deleting WaitToBeDeleted 0 0
minecraft-1 Ready None 0 0
minecraft-2 Ready None 0 0
# After a while
...
kubectl get gs
NAME STATE OPSSTATE DP UP
minecraft-1 Ready None 0 0
minecraft-2 Ready None 0 0
```

4
go.mod
View File

@ -8,6 +8,8 @@ require (
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
github.com/openkruise/kruise-api v1.3.0
google.golang.org/grpc v1.40.0
google.golang.org/protobuf v1.27.1
k8s.io/api v0.24.0
k8s.io/apimachinery v0.24.0
k8s.io/client-go v0.24.0
@ -75,7 +77,7 @@ require (
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

2
go.sum
View File

@ -865,6 +865,7 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA=
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@ -887,6 +888,7 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

16
main.go
View File

@ -23,7 +23,10 @@ import (
"github.com/openkruise/kruise-game/cloudprovider"
cpmanager "github.com/openkruise/kruise-game/cloudprovider/manager"
controller "github.com/openkruise/kruise-game/pkg/controllers"
"github.com/openkruise/kruise-game/pkg/externalscaler"
"github.com/openkruise/kruise-game/pkg/webhook"
"google.golang.org/grpc"
"net"
"os"
"time"
@ -66,6 +69,7 @@ func main() {
var probeAddr string
var namespace string
var syncPeriodStr string
var scaleServerAddr string
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8082", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
@ -74,6 +78,7 @@ func main() {
flag.StringVar(&namespace, "namespace", "",
"Namespace if specified restricts the manager's cache to watch objects in the desired namespace. Defaults to all namespaces.")
flag.StringVar(&syncPeriodStr, "sync-period", "", "Determines the minimum frequency at which watched resources are reconciled.")
flag.StringVar(&scaleServerAddr, "scale-server-bind-address", ":6000", "The address the scale server endpoint binds to.")
// Add cloud provider flags
cloudprovider.InitCloudProviderFlags()
@ -164,6 +169,17 @@ func main() {
}
}()
externalScaler := externalscaler.NewExternalScaler(mgr.GetClient())
go func() {
grpcServer := grpc.NewServer()
lis, _ := net.Listen("tcp", scaleServerAddr)
externalscaler.RegisterExternalScalerServer(grpcServer, externalScaler)
if err := grpcServer.Serve(lis); err != nil {
setupLog.Error(err, "unable to setup ExternalScalerServer")
os.Exit(1)
}
}()
setupLog.Info("starting kruise-game-manager")
if err := mgr.Start(signal); err != nil {

View File

@ -0,0 +1,75 @@
package externalscaler
import (
"context"
"fmt"
gamekruiseiov1alpha1 "github.com/openkruise/kruise-game/apis/v1alpha1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type ExternalScaler struct {
client client.Client
}
func (e *ExternalScaler) mustEmbedUnimplementedExternalScalerServer() {
}
func (e *ExternalScaler) IsActive(ctx context.Context, scaledObject *ScaledObjectRef) (*IsActiveResponse, error) {
return &IsActiveResponse{
Result: true,
}, nil
}
func (e *ExternalScaler) StreamIsActive(scaledObject *ScaledObjectRef, epsServer ExternalScaler_StreamIsActiveServer) error {
return nil
}
func (e *ExternalScaler) GetMetricSpec(ctx context.Context, scaledObjectRef *ScaledObjectRef) (*GetMetricSpecResponse, error) {
name := scaledObjectRef.GetName()
ns := scaledObjectRef.GetNamespace()
gss := &gamekruiseiov1alpha1.GameServerSet{}
err := e.client.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, gss)
if err != nil {
klog.Error(err)
return nil, err
}
desireReplicas := gss.Spec.Replicas
klog.Infof("GameServerSet %s/%s TargetSize is %d", ns, name, *desireReplicas)
return &GetMetricSpecResponse{
MetricSpecs: []*MetricSpec{{
MetricName: "gssReplicas",
TargetSize: int64(*desireReplicas),
}},
}, nil
}
func (e *ExternalScaler) GetMetrics(ctx context.Context, metricRequest *GetMetricsRequest) (*GetMetricsResponse, error) {
name := metricRequest.ScaledObjectRef.GetName()
ns := metricRequest.ScaledObjectRef.GetNamespace()
gss := &gamekruiseiov1alpha1.GameServerSet{}
err := e.client.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, gss)
if err != nil {
klog.Error(err)
return nil, err
}
currentReplicas := gss.Status.CurrentReplicas
numWaitToBeDeleted := gss.Status.WaitToBeDeletedReplicas
if numWaitToBeDeleted == nil || currentReplicas == 0 {
return nil, fmt.Errorf("GameServerSet %s/%s has not inited", ns, name)
}
klog.Infof("GameServerSet %s/%s desire replicas is %d", ns, name, currentReplicas-*numWaitToBeDeleted)
return &GetMetricsResponse{
MetricValues: []*MetricValue{{
MetricName: "gssReplicas",
MetricValue: int64(currentReplicas - *numWaitToBeDeleted),
}},
}, nil
}
func NewExternalScaler(client client.Client) *ExternalScaler {
return &ExternalScaler{
client: client,
}
}

View File

@ -0,0 +1,622 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc v4.22.0--rc2
// source: externalscaler.proto
package externalscaler
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ScaledObjectRef struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"`
ScalerMetadata map[string]string `protobuf:"bytes,3,rep,name=scalerMetadata,proto3" json:"scalerMetadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *ScaledObjectRef) Reset() {
*x = ScaledObjectRef{}
if protoimpl.UnsafeEnabled {
mi := &file_externalscaler_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ScaledObjectRef) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ScaledObjectRef) ProtoMessage() {}
func (x *ScaledObjectRef) ProtoReflect() protoreflect.Message {
mi := &file_externalscaler_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ScaledObjectRef.ProtoReflect.Descriptor instead.
func (*ScaledObjectRef) Descriptor() ([]byte, []int) {
return file_externalscaler_proto_rawDescGZIP(), []int{0}
}
func (x *ScaledObjectRef) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *ScaledObjectRef) GetNamespace() string {
if x != nil {
return x.Namespace
}
return ""
}
func (x *ScaledObjectRef) GetScalerMetadata() map[string]string {
if x != nil {
return x.ScalerMetadata
}
return nil
}
type IsActiveResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Result bool `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"`
}
func (x *IsActiveResponse) Reset() {
*x = IsActiveResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_externalscaler_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IsActiveResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IsActiveResponse) ProtoMessage() {}
func (x *IsActiveResponse) ProtoReflect() protoreflect.Message {
mi := &file_externalscaler_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IsActiveResponse.ProtoReflect.Descriptor instead.
func (*IsActiveResponse) Descriptor() ([]byte, []int) {
return file_externalscaler_proto_rawDescGZIP(), []int{1}
}
func (x *IsActiveResponse) GetResult() bool {
if x != nil {
return x.Result
}
return false
}
type GetMetricSpecResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MetricSpecs []*MetricSpec `protobuf:"bytes,1,rep,name=metricSpecs,proto3" json:"metricSpecs,omitempty"`
}
func (x *GetMetricSpecResponse) Reset() {
*x = GetMetricSpecResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_externalscaler_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetMetricSpecResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetMetricSpecResponse) ProtoMessage() {}
func (x *GetMetricSpecResponse) ProtoReflect() protoreflect.Message {
mi := &file_externalscaler_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetMetricSpecResponse.ProtoReflect.Descriptor instead.
func (*GetMetricSpecResponse) Descriptor() ([]byte, []int) {
return file_externalscaler_proto_rawDescGZIP(), []int{2}
}
func (x *GetMetricSpecResponse) GetMetricSpecs() []*MetricSpec {
if x != nil {
return x.MetricSpecs
}
return nil
}
type MetricSpec struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MetricName string `protobuf:"bytes,1,opt,name=metricName,proto3" json:"metricName,omitempty"`
TargetSize int64 `protobuf:"varint,2,opt,name=targetSize,proto3" json:"targetSize,omitempty"`
}
func (x *MetricSpec) Reset() {
*x = MetricSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_externalscaler_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MetricSpec) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MetricSpec) ProtoMessage() {}
func (x *MetricSpec) ProtoReflect() protoreflect.Message {
mi := &file_externalscaler_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use MetricSpec.ProtoReflect.Descriptor instead.
func (*MetricSpec) Descriptor() ([]byte, []int) {
return file_externalscaler_proto_rawDescGZIP(), []int{3}
}
func (x *MetricSpec) GetMetricName() string {
if x != nil {
return x.MetricName
}
return ""
}
func (x *MetricSpec) GetTargetSize() int64 {
if x != nil {
return x.TargetSize
}
return 0
}
type GetMetricsRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ScaledObjectRef *ScaledObjectRef `protobuf:"bytes,1,opt,name=scaledObjectRef,proto3" json:"scaledObjectRef,omitempty"`
MetricName string `protobuf:"bytes,2,opt,name=metricName,proto3" json:"metricName,omitempty"`
}
func (x *GetMetricsRequest) Reset() {
*x = GetMetricsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_externalscaler_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetMetricsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetMetricsRequest) ProtoMessage() {}
func (x *GetMetricsRequest) ProtoReflect() protoreflect.Message {
mi := &file_externalscaler_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetMetricsRequest.ProtoReflect.Descriptor instead.
func (*GetMetricsRequest) Descriptor() ([]byte, []int) {
return file_externalscaler_proto_rawDescGZIP(), []int{4}
}
func (x *GetMetricsRequest) GetScaledObjectRef() *ScaledObjectRef {
if x != nil {
return x.ScaledObjectRef
}
return nil
}
func (x *GetMetricsRequest) GetMetricName() string {
if x != nil {
return x.MetricName
}
return ""
}
type GetMetricsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MetricValues []*MetricValue `protobuf:"bytes,1,rep,name=metricValues,proto3" json:"metricValues,omitempty"`
}
func (x *GetMetricsResponse) Reset() {
*x = GetMetricsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_externalscaler_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetMetricsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetMetricsResponse) ProtoMessage() {}
func (x *GetMetricsResponse) ProtoReflect() protoreflect.Message {
mi := &file_externalscaler_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetMetricsResponse.ProtoReflect.Descriptor instead.
func (*GetMetricsResponse) Descriptor() ([]byte, []int) {
return file_externalscaler_proto_rawDescGZIP(), []int{5}
}
func (x *GetMetricsResponse) GetMetricValues() []*MetricValue {
if x != nil {
return x.MetricValues
}
return nil
}
type MetricValue struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
MetricName string `protobuf:"bytes,1,opt,name=metricName,proto3" json:"metricName,omitempty"`
MetricValue int64 `protobuf:"varint,2,opt,name=metricValue,proto3" json:"metricValue,omitempty"`
}
func (x *MetricValue) Reset() {
*x = MetricValue{}
if protoimpl.UnsafeEnabled {
mi := &file_externalscaler_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MetricValue) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MetricValue) ProtoMessage() {}
func (x *MetricValue) ProtoReflect() protoreflect.Message {
mi := &file_externalscaler_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use MetricValue.ProtoReflect.Descriptor instead.
func (*MetricValue) Descriptor() ([]byte, []int) {
return file_externalscaler_proto_rawDescGZIP(), []int{6}
}
func (x *MetricValue) GetMetricName() string {
if x != nil {
return x.MetricName
}
return ""
}
func (x *MetricValue) GetMetricValue() int64 {
if x != nil {
return x.MetricValue
}
return 0
}
var File_externalscaler_proto protoreflect.FileDescriptor
var file_externalscaler_proto_rawDesc = []byte{
0x0a, 0x14, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x22, 0xe3, 0x01, 0x0a, 0x0f, 0x53, 0x63, 0x61, 0x6c, 0x65,
0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c,
0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x0e,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x52, 0x65, 0x66, 0x2e, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x41, 0x0a, 0x13, 0x53, 0x63, 0x61,
0x6c, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2a, 0x0a, 0x10,
0x49, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x55, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4d,
0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x70, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x70, 0x65, 0x63, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,
0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x70,
0x65, 0x63, 0x52, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x70, 0x65, 0x63, 0x73, 0x22,
0x4c, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1e, 0x0a,
0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a,
0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x7e, 0x0a,
0x11, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x49, 0x0a, 0x0f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x78,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x61,
0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x52, 0x0f, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x12, 0x1e, 0x0a,
0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x55, 0x0a,
0x12, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x78, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69,
0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e,
0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x32, 0xec, 0x02, 0x0a, 0x0e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x08, 0x49, 0x73, 0x41, 0x63,
0x74, 0x69, 0x76, 0x65, 0x12, 0x1f, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x52, 0x65, 0x66, 0x1a, 0x20, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x49, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x49, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1f, 0x2e, 0x65, 0x78,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x61,
0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x1a, 0x20, 0x2e, 0x65,
0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x49, 0x73,
0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x30, 0x01, 0x12, 0x59, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53,
0x70, 0x65, 0x63, 0x12, 0x1f, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63,
0x61, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63,
0x74, 0x52, 0x65, 0x66, 0x1a, 0x25, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73,
0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53,
0x70, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a,
0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x21, 0x2e, 0x65, 0x78,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74,
0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22,
0x2e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x2e,
0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x42, 0x12, 0x5a, 0x10, 0x2e, 0x3b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_externalscaler_proto_rawDescOnce sync.Once
file_externalscaler_proto_rawDescData = file_externalscaler_proto_rawDesc
)
func file_externalscaler_proto_rawDescGZIP() []byte {
file_externalscaler_proto_rawDescOnce.Do(func() {
file_externalscaler_proto_rawDescData = protoimpl.X.CompressGZIP(file_externalscaler_proto_rawDescData)
})
return file_externalscaler_proto_rawDescData
}
var file_externalscaler_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_externalscaler_proto_goTypes = []interface{}{
(*ScaledObjectRef)(nil), // 0: externalscaler.ScaledObjectRef
(*IsActiveResponse)(nil), // 1: externalscaler.IsActiveResponse
(*GetMetricSpecResponse)(nil), // 2: externalscaler.GetMetricSpecResponse
(*MetricSpec)(nil), // 3: externalscaler.MetricSpec
(*GetMetricsRequest)(nil), // 4: externalscaler.GetMetricsRequest
(*GetMetricsResponse)(nil), // 5: externalscaler.GetMetricsResponse
(*MetricValue)(nil), // 6: externalscaler.MetricValue
nil, // 7: externalscaler.ScaledObjectRef.ScalerMetadataEntry
}
var file_externalscaler_proto_depIdxs = []int32{
7, // 0: externalscaler.ScaledObjectRef.scalerMetadata:type_name -> externalscaler.ScaledObjectRef.ScalerMetadataEntry
3, // 1: externalscaler.GetMetricSpecResponse.metricSpecs:type_name -> externalscaler.MetricSpec
0, // 2: externalscaler.GetMetricsRequest.scaledObjectRef:type_name -> externalscaler.ScaledObjectRef
6, // 3: externalscaler.GetMetricsResponse.metricValues:type_name -> externalscaler.MetricValue
0, // 4: externalscaler.ExternalScaler.IsActive:input_type -> externalscaler.ScaledObjectRef
0, // 5: externalscaler.ExternalScaler.StreamIsActive:input_type -> externalscaler.ScaledObjectRef
0, // 6: externalscaler.ExternalScaler.GetMetricSpec:input_type -> externalscaler.ScaledObjectRef
4, // 7: externalscaler.ExternalScaler.GetMetrics:input_type -> externalscaler.GetMetricsRequest
1, // 8: externalscaler.ExternalScaler.IsActive:output_type -> externalscaler.IsActiveResponse
1, // 9: externalscaler.ExternalScaler.StreamIsActive:output_type -> externalscaler.IsActiveResponse
2, // 10: externalscaler.ExternalScaler.GetMetricSpec:output_type -> externalscaler.GetMetricSpecResponse
5, // 11: externalscaler.ExternalScaler.GetMetrics:output_type -> externalscaler.GetMetricsResponse
8, // [8:12] is the sub-list for method output_type
4, // [4:8] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_externalscaler_proto_init() }
func file_externalscaler_proto_init() {
if File_externalscaler_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_externalscaler_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ScaledObjectRef); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_externalscaler_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IsActiveResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_externalscaler_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetMetricSpecResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_externalscaler_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MetricSpec); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_externalscaler_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetMetricsRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_externalscaler_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetMetricsResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_externalscaler_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MetricValue); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_externalscaler_proto_rawDesc,
NumEnums: 0,
NumMessages: 8,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_externalscaler_proto_goTypes,
DependencyIndexes: file_externalscaler_proto_depIdxs,
MessageInfos: file_externalscaler_proto_msgTypes,
}.Build()
File_externalscaler_proto = out.File
file_externalscaler_proto_rawDesc = nil
file_externalscaler_proto_goTypes = nil
file_externalscaler_proto_depIdxs = nil
}

View File

@ -0,0 +1,241 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v4.22.0--rc2
// source: externalscaler.proto
package externalscaler
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// ExternalScalerClient is the client API for ExternalScaler service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ExternalScalerClient interface {
IsActive(ctx context.Context, in *ScaledObjectRef, opts ...grpc.CallOption) (*IsActiveResponse, error)
StreamIsActive(ctx context.Context, in *ScaledObjectRef, opts ...grpc.CallOption) (ExternalScaler_StreamIsActiveClient, error)
GetMetricSpec(ctx context.Context, in *ScaledObjectRef, opts ...grpc.CallOption) (*GetMetricSpecResponse, error)
GetMetrics(ctx context.Context, in *GetMetricsRequest, opts ...grpc.CallOption) (*GetMetricsResponse, error)
}
type externalScalerClient struct {
cc grpc.ClientConnInterface
}
func NewExternalScalerClient(cc grpc.ClientConnInterface) ExternalScalerClient {
return &externalScalerClient{cc}
}
func (c *externalScalerClient) IsActive(ctx context.Context, in *ScaledObjectRef, opts ...grpc.CallOption) (*IsActiveResponse, error) {
out := new(IsActiveResponse)
err := c.cc.Invoke(ctx, "/externalscaler.ExternalScaler/IsActive", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *externalScalerClient) StreamIsActive(ctx context.Context, in *ScaledObjectRef, opts ...grpc.CallOption) (ExternalScaler_StreamIsActiveClient, error) {
stream, err := c.cc.NewStream(ctx, &ExternalScaler_ServiceDesc.Streams[0], "/externalscaler.ExternalScaler/StreamIsActive", opts...)
if err != nil {
return nil, err
}
x := &externalScalerStreamIsActiveClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type ExternalScaler_StreamIsActiveClient interface {
Recv() (*IsActiveResponse, error)
grpc.ClientStream
}
type externalScalerStreamIsActiveClient struct {
grpc.ClientStream
}
func (x *externalScalerStreamIsActiveClient) Recv() (*IsActiveResponse, error) {
m := new(IsActiveResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *externalScalerClient) GetMetricSpec(ctx context.Context, in *ScaledObjectRef, opts ...grpc.CallOption) (*GetMetricSpecResponse, error) {
out := new(GetMetricSpecResponse)
err := c.cc.Invoke(ctx, "/externalscaler.ExternalScaler/GetMetricSpec", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *externalScalerClient) GetMetrics(ctx context.Context, in *GetMetricsRequest, opts ...grpc.CallOption) (*GetMetricsResponse, error) {
out := new(GetMetricsResponse)
err := c.cc.Invoke(ctx, "/externalscaler.ExternalScaler/GetMetrics", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ExternalScalerServer is the server API for ExternalScaler service.
// All implementations must embed UnimplementedExternalScalerServer
// for forward compatibility
type ExternalScalerServer interface {
IsActive(context.Context, *ScaledObjectRef) (*IsActiveResponse, error)
StreamIsActive(*ScaledObjectRef, ExternalScaler_StreamIsActiveServer) error
GetMetricSpec(context.Context, *ScaledObjectRef) (*GetMetricSpecResponse, error)
GetMetrics(context.Context, *GetMetricsRequest) (*GetMetricsResponse, error)
mustEmbedUnimplementedExternalScalerServer()
}
// UnimplementedExternalScalerServer must be embedded to have forward compatible implementations.
type UnimplementedExternalScalerServer struct {
}
func (UnimplementedExternalScalerServer) IsActive(context.Context, *ScaledObjectRef) (*IsActiveResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method IsActive not implemented")
}
func (UnimplementedExternalScalerServer) StreamIsActive(*ScaledObjectRef, ExternalScaler_StreamIsActiveServer) error {
return status.Errorf(codes.Unimplemented, "method StreamIsActive not implemented")
}
func (UnimplementedExternalScalerServer) GetMetricSpec(context.Context, *ScaledObjectRef) (*GetMetricSpecResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetMetricSpec not implemented")
}
func (UnimplementedExternalScalerServer) GetMetrics(context.Context, *GetMetricsRequest) (*GetMetricsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetMetrics not implemented")
}
func (UnimplementedExternalScalerServer) mustEmbedUnimplementedExternalScalerServer() {}
// UnsafeExternalScalerServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ExternalScalerServer will
// result in compilation errors.
type UnsafeExternalScalerServer interface {
mustEmbedUnimplementedExternalScalerServer()
}
func RegisterExternalScalerServer(s grpc.ServiceRegistrar, srv ExternalScalerServer) {
s.RegisterService(&ExternalScaler_ServiceDesc, srv)
}
func _ExternalScaler_IsActive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ScaledObjectRef)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ExternalScalerServer).IsActive(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/externalscaler.ExternalScaler/IsActive",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ExternalScalerServer).IsActive(ctx, req.(*ScaledObjectRef))
}
return interceptor(ctx, in, info, handler)
}
func _ExternalScaler_StreamIsActive_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(ScaledObjectRef)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(ExternalScalerServer).StreamIsActive(m, &externalScalerStreamIsActiveServer{stream})
}
type ExternalScaler_StreamIsActiveServer interface {
Send(*IsActiveResponse) error
grpc.ServerStream
}
type externalScalerStreamIsActiveServer struct {
grpc.ServerStream
}
func (x *externalScalerStreamIsActiveServer) Send(m *IsActiveResponse) error {
return x.ServerStream.SendMsg(m)
}
func _ExternalScaler_GetMetricSpec_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ScaledObjectRef)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ExternalScalerServer).GetMetricSpec(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/externalscaler.ExternalScaler/GetMetricSpec",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ExternalScalerServer).GetMetricSpec(ctx, req.(*ScaledObjectRef))
}
return interceptor(ctx, in, info, handler)
}
func _ExternalScaler_GetMetrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetMetricsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ExternalScalerServer).GetMetrics(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/externalscaler.ExternalScaler/GetMetrics",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ExternalScalerServer).GetMetrics(ctx, req.(*GetMetricsRequest))
}
return interceptor(ctx, in, info, handler)
}
// ExternalScaler_ServiceDesc is the grpc.ServiceDesc for ExternalScaler service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ExternalScaler_ServiceDesc = grpc.ServiceDesc{
ServiceName: "externalscaler.ExternalScaler",
HandlerType: (*ExternalScalerServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "IsActive",
Handler: _ExternalScaler_IsActive_Handler,
},
{
MethodName: "GetMetricSpec",
Handler: _ExternalScaler_GetMetricSpec_Handler,
},
{
MethodName: "GetMetrics",
Handler: _ExternalScaler_GetMetrics_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "StreamIsActive",
Handler: _ExternalScaler_StreamIsActive_Handler,
ServerStreams: true,
},
},
Metadata: "externalscaler.proto",
}

View File

@ -0,0 +1,44 @@
syntax = "proto3";
package externalscaler;
option go_package = ".;externalscaler";
service ExternalScaler {
rpc IsActive(ScaledObjectRef) returns (IsActiveResponse) {}
rpc StreamIsActive(ScaledObjectRef) returns (stream IsActiveResponse) {}
rpc GetMetricSpec(ScaledObjectRef) returns (GetMetricSpecResponse) {}
rpc GetMetrics(GetMetricsRequest) returns (GetMetricsResponse) {}
}
message ScaledObjectRef {
string name = 1;
string namespace = 2;
map<string, string> scalerMetadata = 3;
}
message IsActiveResponse {
bool result = 1;
}
message GetMetricSpecResponse {
repeated MetricSpec metricSpecs = 1;
}
message MetricSpec {
string metricName = 1;
int64 targetSize = 2;
}
message GetMetricsRequest {
ScaledObjectRef scaledObjectRef = 1;
string metricName = 2;
}
message GetMetricsResponse {
repeated MetricValue metricValues = 1;
}
message MetricValue {
string metricName = 1;
int64 metricValue = 2;
}