mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 18:31:15 +00:00
Merge pull request #96012 from khenidak/clusterIPs-labeling
add tests that update services while gate is off
This commit is contained in:
commit
ba75a6dbd7
@ -16,6 +16,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/api/discovery/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/discovery/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
@ -24,6 +25,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||||
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
|
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
|
||||||
"//test/integration/framework:go_default_library",
|
"//test/integration/framework:go_default_library",
|
||||||
|
"//vendor/github.com/evanphx/json-patch:go_default_library",
|
||||||
"//vendor/k8s.io/utils/net:go_default_library",
|
"//vendor/k8s.io/utils/net:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -18,6 +18,7 @@ package dualstack
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -25,9 +26,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
jsonpatch "github.com/evanphx/json-patch"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
|
||||||
@ -1305,6 +1310,129 @@ func TestPreferDualStack(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type labelsForMergePatch struct {
|
||||||
|
Labels map[string]string `json:"lables,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// tests an update service while dualstack flag is off
|
||||||
|
func TestServiceUpdate(t *testing.T) {
|
||||||
|
// Create an IPv4 single stack control-plane
|
||||||
|
serviceCIDR := "10.0.0.0/16"
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, false)()
|
||||||
|
|
||||||
|
cfg := framework.NewIntegrationTestMasterConfig()
|
||||||
|
_, cidr, err := net.ParseCIDR(serviceCIDR)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("bad cidr: %v", err)
|
||||||
|
}
|
||||||
|
cfg.ExtraConfig.ServiceIPRange = *cidr
|
||||||
|
_, s, closeFn := framework.RunAMaster(cfg)
|
||||||
|
defer closeFn()
|
||||||
|
|
||||||
|
client := clientset.NewForConfigOrDie(&restclient.Config{Host: s.URL})
|
||||||
|
|
||||||
|
// Wait until the default "kubernetes" service is created.
|
||||||
|
if err = wait.Poll(250*time.Millisecond, time.Minute, func() (bool, error) {
|
||||||
|
_, err := client.CoreV1().Services(metav1.NamespaceDefault).Get(context.TODO(), "kubernetes", metav1.GetOptions{})
|
||||||
|
if err != nil && !apierrors.IsNotFound(err) {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return !apierrors.IsNotFound(err), nil
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("creating kubernetes service timed out")
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceName := "test-service"
|
||||||
|
svc := &v1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: serviceName,
|
||||||
|
},
|
||||||
|
Spec: v1.ServiceSpec{
|
||||||
|
Type: v1.ServiceTypeClusterIP,
|
||||||
|
Ports: []v1.ServicePort{
|
||||||
|
{
|
||||||
|
Port: 443,
|
||||||
|
TargetPort: intstr.FromInt(443),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the service
|
||||||
|
_, err = client.CoreV1().Services(metav1.NamespaceDefault).Create(context.TODO(), svc, metav1.CreateOptions{})
|
||||||
|
// if no error was expected validate the service otherwise return
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error creating service:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
svc, err = client.CoreV1().Services(metav1.NamespaceDefault).Get(context.TODO(), svc.Name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error to get the service %s %v", svc.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update using put
|
||||||
|
svc.Labels = map[string]string{"x": "y"}
|
||||||
|
_, err = client.CoreV1().Services(metav1.NamespaceDefault).Update(context.TODO(), svc, metav1.UpdateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error updating the service %s %v", svc.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.CoreV1().Services(metav1.NamespaceDefault).Get(context.TODO(), svc.Name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error to get the service %s %v", svc.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update using StrategicMergePatchType
|
||||||
|
labels := labelsForMergePatch{
|
||||||
|
Labels: map[string]string{"foo": "bar"},
|
||||||
|
}
|
||||||
|
|
||||||
|
patchBytes, err := json.Marshal(&labels)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to json.Marshal labels: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.CoreV1().Services(metav1.NamespaceDefault).Patch(context.TODO(), svc.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error patching service using strategic merge patch. %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
current, err := client.CoreV1().Services(metav1.NamespaceDefault).Get(context.TODO(), svc.Name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error to get the service %s %v", svc.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update using json patch
|
||||||
|
toUpdate := current.DeepCopy()
|
||||||
|
currentJSON, err := json.Marshal(current)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error marshal current service. %v", err)
|
||||||
|
}
|
||||||
|
toUpdate.Labels = map[string]string{"alpha": "bravo"}
|
||||||
|
toUpdateJSON, err := json.Marshal(toUpdate)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error marshal toupdate service. %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
patchBytes, err = jsonpatch.CreateMergePatch(currentJSON, toUpdateJSON)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error creating json patch. %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.CoreV1().Services(metav1.NamespaceDefault).Patch(context.TODO(), svc.Name, types.MergePatchType, patchBytes, metav1.PatchOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error patching service using merge patch. %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate the service was created correctly if it was not expected to fail
|
||||||
|
_, err = client.CoreV1().Services(metav1.NamespaceDefault).Get(context.TODO(), svc.Name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error to get the service %s %v", svc.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// validateServiceAndClusterIPFamily checks that the service has the expected IPFamilies
|
// validateServiceAndClusterIPFamily checks that the service has the expected IPFamilies
|
||||||
func validateServiceAndClusterIPFamily(svc *v1.Service, expectedIPFamilies []v1.IPFamily) error {
|
func validateServiceAndClusterIPFamily(svc *v1.Service, expectedIPFamilies []v1.IPFamily) error {
|
||||||
// create a slice for the errors
|
// create a slice for the errors
|
||||||
|
Loading…
Reference in New Issue
Block a user