Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cloudprovider/exteranlgrpc): properly handle unimplemented methods #5937

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"context"
"fmt"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/anypb"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -113,6 +115,9 @@ func (w *Wrapper) PricingNodePrice(_ context.Context, req *protos.PricingNodePri

model, err := w.provider.Pricing()
if err != nil {
if err == cloudprovider.ErrNotImplemented {
return nil, status.Error(codes.Unimplemented, err.Error())
}
return nil, err
}
reqNode := req.GetNode()
Expand All @@ -136,6 +141,9 @@ func (w *Wrapper) PricingPodPrice(_ context.Context, req *protos.PricingPodPrice

model, err := w.provider.Pricing()
if err != nil {
if err == cloudprovider.ErrNotImplemented {
return nil, status.Error(codes.Unimplemented, err.Error())
}
return nil, err
}
reqPod := req.GetPod()
Expand Down Expand Up @@ -326,6 +334,9 @@ func (w *Wrapper) NodeGroupTemplateNodeInfo(_ context.Context, req *protos.NodeG
}
info, err := ng.TemplateNodeInfo()
if err != nil {
if err == cloudprovider.ErrNotImplemented {
return nil, status.Error(codes.Unimplemented, err.Error())
}
return nil, err
}
return &protos.NodeGroupTemplateNodeInfoResponse{
Expand Down Expand Up @@ -355,6 +366,9 @@ func (w *Wrapper) NodeGroupGetOptions(_ context.Context, req *protos.NodeGroupAu
}
opts, err := ng.GetOptions(defaults)
if err != nil {
if err == cloudprovider.ErrNotImplemented {
return nil, status.Error(codes.Unimplemented, err.Error())
}
return nil, err
}
if opts == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import (
"time"

"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/status"
"gopkg.in/yaml.v2"
apiv1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -158,6 +160,10 @@ func (m *pricingModel) NodePrice(node *apiv1.Node, startTime time.Time, endTime
EndTime: &end,
})
if err != nil {
st, ok := status.FromError(err)
if ok && st.Code() == codes.Unimplemented {
return 0, cloudprovider.ErrNotImplemented
}
klog.V(1).Infof("Error on gRPC call PricingNodePrice: %v", err)
return 0, err
}
Expand All @@ -178,6 +184,10 @@ func (m *pricingModel) PodPrice(pod *apiv1.Pod, startTime time.Time, endTime tim
EndTime: &end,
})
if err != nil {
st, ok := status.FromError(err)
if ok && st.Code() == codes.Unimplemented {
return 0, cloudprovider.ErrNotImplemented
dbonfigli marked this conversation as resolved.
Show resolved Hide resolved
}
klog.V(1).Infof("Error on gRPC call PricingPodPrice: %v", err)
return 0, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/anypb"
apiv1 "k8s.io/api/core/v1"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/externalgrpc/protos"
)

Expand Down Expand Up @@ -286,6 +289,23 @@ func TestCloudProvider_Pricing(t *testing.T) {
_, err = model.NodePrice(apiv1Node3, time.Time{}, time.Time{})
assert.Error(t, err)

// test notImplemented for NodePrice
m.On(
"PricingNodePrice", mock.Anything, mock.MatchedBy(func(req *protos.PricingNodePriceRequest) bool {
return req.Node.Name == "node4"
}),
).Return(
&protos.PricingNodePriceResponse{},
status.Error(codes.Unimplemented, "mock error"),
)

apiv1Node4 := &apiv1.Node{}
apiv1Node4.Name = "node4"

_, err = model.NodePrice(apiv1Node4, time.Time{}, time.Time{})
assert.Error(t, err)
assert.Equal(t, cloudprovider.ErrNotImplemented, err)

// test correct PodPrice call
m.On(
"PricingPodPrice", mock.Anything, mock.MatchedBy(func(req *protos.PricingPodPriceRequest) bool {
Expand Down Expand Up @@ -333,6 +353,24 @@ func TestCloudProvider_Pricing(t *testing.T) {

_, err = model.PodPrice(apiv1Pod3, time.Time{}, time.Time{})
assert.Error(t, err)

// test notImplemented for PodPrice
m.On(
"PricingPodPrice", mock.Anything, mock.MatchedBy(func(req *protos.PricingPodPriceRequest) bool {
return req.Pod.Name == "pod4"
}),
).Return(
&protos.PricingPodPriceResponse{},
status.Error(codes.Unimplemented, "mock error"),
)

apiv1Pod4 := &apiv1.Pod{}
apiv1Pod4.Name = "pod4"

_, err = model.PodPrice(apiv1Pod4, time.Time{}, time.Time{})
assert.Error(t, err)
assert.Equal(t, cloudprovider.ErrNotImplemented, err)

}

func TestCloudProvider_GPULabel(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"context"
"sync"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
Expand Down Expand Up @@ -206,6 +208,10 @@ func (n *NodeGroup) TemplateNodeInfo() (*schedulerframework.NodeInfo, error) {
Id: n.id,
})
if err != nil {
st, ok := status.FromError(err)
if ok && st.Code() == codes.Unimplemented {
return nil, cloudprovider.ErrNotImplemented
}
klog.V(1).Infof("Error on gRPC call NodeGroupTemplateNodeInfo: %v", err)
return nil, err
}
Expand Down Expand Up @@ -269,6 +275,10 @@ func (n *NodeGroup) GetOptions(defaults config.NodeGroupAutoscalingOptions) (*co
},
})
if err != nil {
st, ok := status.FromError(err)
if ok && st.Code() == codes.Unimplemented {
return nil, cloudprovider.ErrNotImplemented
}
klog.V(1).Infof("Error on gRPC call NodeGroupGetOptions: %v", err)
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
apiv1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
Expand Down Expand Up @@ -208,6 +210,27 @@ func TestCloudProvider_TemplateNodeInfo(t *testing.T) {
_, err = ng4.TemplateNodeInfo()
assert.Error(t, err)

// test notImplemented
m.On(
"NodeGroupTemplateNodeInfo", mock.Anything, mock.MatchedBy(func(req *protos.NodeGroupTemplateNodeInfoRequest) bool {
return req.Id == "nodeGroup5"
}),
).Return(
&protos.NodeGroupTemplateNodeInfoResponse{
NodeInfo: nil,
},
status.Error(codes.Unimplemented, "mock error"),
).Once()

ng5 := NodeGroup{
id: "nodeGroup5",
client: client,
}

_, err = ng5.TemplateNodeInfo()
assert.Error(t, err)
assert.Equal(t, cloudprovider.ErrNotImplemented, err)

}

func TestCloudProvider_GetOptions(t *testing.T) {
Expand Down Expand Up @@ -289,6 +312,26 @@ func TestCloudProvider_GetOptions(t *testing.T) {
opts, err = ng3.GetOptions(defaultsOpts)
assert.NoError(t, err)
assert.Nil(t, opts)

// test notImplemented
m.On(
"NodeGroupGetOptions", mock.Anything, mock.MatchedBy(func(req *protos.NodeGroupAutoscalingOptionsRequest) bool {
return req.Id == "nodeGroup4"
}),
).Return(
&protos.NodeGroupAutoscalingOptionsResponse{},
status.Error(codes.Unimplemented, "mock error"),
)

ng4 := NodeGroup{
id: "nodeGroup4",
client: client,
}

_, err = ng4.GetOptions(defaultsOpts)
assert.Error(t, err)
assert.Equal(t, cloudprovider.ErrNotImplemented, err)

}

func TestCloudProvider_TargetSize(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ service CloudProvider {

// PricingNodePrice returns a theoretical minimum price of running a node for
// a given period of time on a perfectly matching machine.
// Implementation optional.
// Implementation optional: if unimplemented return error code 12 (for `Unimplemented`)
rpc PricingNodePrice(PricingNodePriceRequest)
returns (PricingNodePriceResponse) {}

// PricingPodPrice returns a theoretical minimum price of running a pod for a given
// period of time on a perfectly matching machine.
// Implementation optional.
// Implementation optional: if unimplemented return error code 12 (for `Unimplemented`)
rpc PricingPodPrice(PricingPodPriceRequest)
returns (PricingPodPriceResponse) {}

Expand Down Expand Up @@ -103,13 +103,13 @@ service CloudProvider {
// NodeGroupTemplateNodeInfo returns a structure of an empty (as if just started) node,
// with all of the labels, capacity and allocatable information. This will be used in
// scale-up simulations to predict what would a new node look like if a node group was expanded.
// Implementation optional.
// Implementation optional: if unimplemented return error code 12 (for `Unimplemented`)
rpc NodeGroupTemplateNodeInfo(NodeGroupTemplateNodeInfoRequest)
returns (NodeGroupTemplateNodeInfoResponse) {}

// GetOptions returns NodeGroupAutoscalingOptions that should be used for this particular
// NodeGroup. Returning a grpc error will result in using default options.
// Implementation optional.
// NodeGroup.
// Implementation optional: if unimplemented return error code 12 (for `Unimplemented`)
rpc NodeGroupGetOptions(NodeGroupAutoscalingOptionsRequest)
returns (NodeGroupAutoscalingOptionsResponse) {}
}
Expand Down Expand Up @@ -371,4 +371,3 @@ message NodeGroupAutoscalingOptionsResponse {
// autoscaling options for the requested node.
NodeGroupAutoscalingOptions nodeGroupAutoscalingOptions = 1;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.