Skip to content

Commit

Permalink
Merge pull request #646 from ystia/bugfix/GH-645_deprecated_k8s_apis
Browse files Browse the repository at this point in the history
Fix uses of deprecated k8s apis
  • Loading branch information
loicalbertin committed May 14, 2020
2 parents 4f127ac + 47c07e4 commit 45402f9
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 59 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

### BUG FIXES

* Kubernetes Client uses deprecated apis removed on recent versions of K8S (v1.17+) ([GH-645](https://github.com/ystia/yorc/issues/645))
* Bootstrap may failed with a nil pointer error if download of a component fails ([GH-634](https://github.com/ystia/yorc/issues/634))
* Missing concurrency limit during data migration for logs and events file storage ([GH-640](https://github.com/ystia/yorc/issues/640))
* Unable to undeploy a deployment in progress from Alien4Cloud ([GH-630](https://github.com/ystia/yorc/issues/630))
Expand Down
6 changes: 3 additions & 3 deletions prov/kubernetes/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ package kubernetes

import (
"context"
"github.com/ystia/yorc/v4/storage"
"github.com/ystia/yorc/v4/storage/types"
"github.com/ystia/yorc/v4/tosca"
"testing"

ctu "github.com/hashicorp/consul/testutil"
"github.com/stretchr/testify/require"

"github.com/ystia/yorc/v4/helper/consulutil"
"github.com/ystia/yorc/v4/log"
"github.com/ystia/yorc/v4/storage"
"github.com/ystia/yorc/v4/storage/types"
"github.com/ystia/yorc/v4/tosca"
)

func testsController(t *testing.T, srv *ctu.TestServer) {
Expand Down
21 changes: 11 additions & 10 deletions prov/kubernetes/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,30 @@ package kubernetes
import (
"context"
"fmt"
"github.com/stretchr/testify/require"
"github.com/ystia/yorc/v4/storage"
"github.com/ystia/yorc/v4/storage/types"
"github.com/ystia/yorc/v4/tosca"
"path"
"strconv"
"sync"
"testing"
"time"

"github.com/ystia/yorc/v4/helper/consulutil"
"github.com/ystia/yorc/v4/prov"
"github.com/ystia/yorc/v4/tasks"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"

"github.com/ystia/yorc/v4/helper/consulutil"
"github.com/ystia/yorc/v4/prov"
"github.com/ystia/yorc/v4/storage"
"github.com/ystia/yorc/v4/storage/types"
"github.com/ystia/yorc/v4/tasks"
"github.com/ystia/yorc/v4/tosca"
)

var JSONvalidDeployment = `
{
"apiVersion": "extensions/v1beta1",
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "test-deploy"
Expand Down Expand Up @@ -675,7 +676,7 @@ func testExecutionManageNamespaceDeletion(t *testing.T) {
// One ns "test-ns", 1 controler
k8s1 := newTestSimpleK8s()
k8s1.clientset.CoreV1().Namespaces().Create(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-ns"}})
k8s1.clientset.ExtensionsV1beta1().Deployments("test-ns").Create(&v1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "deploy"}})
k8s1.clientset.AppsV1().Deployments("test-ns").Create(&v1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "deploy"}})

type args struct {
clientset kubernetes.Interface
Expand Down
18 changes: 9 additions & 9 deletions prov/kubernetes/k8s_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import (
"time"

"github.com/pkg/errors"
v1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
Expand All @@ -34,18 +34,18 @@ import (
"github.com/ystia/yorc/v4/events"
)

func isDeploymentFailed(deployment *v1beta1.Deployment) (bool, string) {
func isDeploymentFailed(deployment *v1.Deployment) (bool, string) {
for _, c := range deployment.Status.Conditions {
if c.Type == v1beta1.DeploymentReplicaFailure && c.Status == corev1.ConditionTrue {
if c.Type == v1.DeploymentReplicaFailure && c.Status == corev1.ConditionTrue {
return true, c.Message
} else if c.Type == v1beta1.DeploymentProgressing && c.Status == corev1.ConditionFalse {
} else if c.Type == v1.DeploymentProgressing && c.Status == corev1.ConditionFalse {
return true, c.Message
}
}
return false, ""
}

func streamDeploymentLogs(ctx context.Context, deploymentID string, clientset kubernetes.Interface, deployment *v1beta1.Deployment) {
func streamDeploymentLogs(ctx context.Context, deploymentID string, clientset kubernetes.Interface, deployment *v1.Deployment) {
go func() {
watcher, err := clientset.CoreV1().Events(deployment.Namespace).Watch(metav1.ListOptions{})
if err != nil {
Expand Down Expand Up @@ -104,9 +104,9 @@ func isChildOf(clientset kubernetes.Interface, parent types.UID, ref reference)
case "pod":
om, err = clientset.CoreV1().Pods(ref.Namespace).Get(ref.Name, metav1.GetOptions{})
case "replicaset":
om, err = clientset.ExtensionsV1beta1().ReplicaSets(ref.Namespace).Get(ref.Name, metav1.GetOptions{})
om, err = clientset.AppsV1().ReplicaSets(ref.Namespace).Get(ref.Name, metav1.GetOptions{})
case "deployment":
om, err = clientset.ExtensionsV1beta1().Deployments(ref.Namespace).Get(ref.Name, metav1.GetOptions{})
om, err = clientset.AppsV1().Deployments(ref.Namespace).Get(ref.Name, metav1.GetOptions{})
case "job":
om, err = clientset.BatchV1().Jobs(ref.Namespace).Get(ref.Name, metav1.GetOptions{})
default:
Expand All @@ -130,11 +130,11 @@ func isChildOf(clientset kubernetes.Interface, parent types.UID, ref reference)
/* Return the number of pod controllers (Deployment and StatefulSet, more in the future) in a specific namespace or -1, err != nil in case of error */
func podControllersInNamespace(clientset kubernetes.Interface, namespace string) (int, error) {
var nbcontrollers int
deploymentsList, err := clientset.ExtensionsV1beta1().Deployments(namespace).List(metav1.ListOptions{})
deploymentsList, err := clientset.AppsV1().Deployments(namespace).List(metav1.ListOptions{})
if err != nil {
return -1, err
}
stsList, err := clientset.AppsV1beta1().StatefulSets(namespace).List(metav1.ListOptions{})
stsList, err := clientset.AppsV1().StatefulSets(namespace).List(metav1.ListOptions{})
if err != nil {
return -1, err
}
Expand Down
17 changes: 8 additions & 9 deletions prov/kubernetes/k8s_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ import (
"strings"
"testing"

appsv1 "k8s.io/api/apps/v1beta1"
v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -122,9 +121,9 @@ func TestGetNoneExternalIPAdress(t *testing.T) {
Currently support only : StatefulSet, PVC, Service and Deployment */
func mockSupportedResources() map[string]runtime.Object {
pvc := &corev1.PersistentVolumeClaim{ObjectMeta: metav1.ObjectMeta{Name: "pvcTest", Namespace: "test-ns"}}
dep := &v1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "deploymentTest", Namespace: "test-ns"}}
sts := &appsv1.StatefulSet{ObjectMeta: metav1.ObjectMeta{Name: "statefulSetTest", Namespace: "test-ns"},
Spec: appsv1.StatefulSetSpec{}}
dep := &v1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "deploymentTest", Namespace: "test-ns"}}
sts := &v1.StatefulSet{ObjectMeta: metav1.ObjectMeta{Name: "statefulSetTest", Namespace: "test-ns"},
Spec: v1.StatefulSetSpec{}}
svc := &corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: "serviceTest", Namespace: "test-ns"}}
supportedRes := make(map[string]runtime.Object)
supportedRes["persistentvolumeclaims"] = pvc
Expand Down Expand Up @@ -302,7 +301,7 @@ func Test_podControllersInNamespace(t *testing.T) {
"Test one deployment left",
func() kubernetes.Interface {
k8s := newTestSimpleK8s()
k8s.clientset.ExtensionsV1beta1().Deployments(nsName).Create(&v1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "my-deployment", Namespace: nsName}})
k8s.clientset.AppsV1().Deployments(nsName).Create(&v1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "my-deployment", Namespace: nsName}})
return k8s.clientset
},
args{namespace: nsName},
Expand All @@ -312,9 +311,9 @@ func Test_podControllersInNamespace(t *testing.T) {
"Test one deployment & 2 statefulSets left",
func() kubernetes.Interface {
k8s := newTestSimpleK8s()
k8s.clientset.AppsV1beta1().StatefulSets(nsName).Create(&appsv1.StatefulSet{ObjectMeta: metav1.ObjectMeta{Name: "my-statefulset-1", Namespace: nsName}})
k8s.clientset.AppsV1beta1().StatefulSets(nsName).Create(&appsv1.StatefulSet{ObjectMeta: metav1.ObjectMeta{Name: "my-statefulset-2", Namespace: nsName}})
k8s.clientset.ExtensionsV1beta1().Deployments(nsName).Create(&v1beta1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "my-deployment", Namespace: nsName}})
k8s.clientset.AppsV1().StatefulSets(nsName).Create(&v1.StatefulSet{ObjectMeta: metav1.ObjectMeta{Name: "my-statefulset-1", Namespace: nsName}})
k8s.clientset.AppsV1().StatefulSets(nsName).Create(&v1.StatefulSet{ObjectMeta: metav1.ObjectMeta{Name: "my-statefulset-2", Namespace: nsName}})
k8s.clientset.AppsV1().Deployments(nsName).Create(&v1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "my-deployment", Namespace: nsName}})
return k8s.clientset
},
args{namespace: nsName},
Expand Down
50 changes: 25 additions & 25 deletions prov/kubernetes/supported_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ import (
"strconv"

"github.com/pkg/errors"
"github.com/ystia/yorc/v4/deployments"
"github.com/ystia/yorc/v4/events"
appsv1 "k8s.io/api/apps/v1beta1"
v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"

"github.com/ystia/yorc/v4/deployments"
"github.com/ystia/yorc/v4/events"
)

//Interface to implement for new supported objects in K8s
Expand All @@ -56,8 +56,8 @@ type yorcK8sObject interface {
// Supported k8s resources
type yorcK8sPersistentVolumeClaim corev1.PersistentVolumeClaim
type yorcK8sService corev1.Service
type yorcK8sDeployment v1beta1.Deployment
type yorcK8sStatefulSet appsv1.StatefulSet
type yorcK8sDeployment v1.Deployment
type yorcK8sStatefulSet v1.StatefulSet

/*
----------------------------------------------
Expand Down Expand Up @@ -153,28 +153,28 @@ func (yorcDep *yorcK8sDeployment) getObjectMeta() metav1.ObjectMeta {
}

func (yorcDep *yorcK8sDeployment) createResource(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) error {
deploy := v1beta1.Deployment(*yorcDep)
_, err := clientset.ExtensionsV1beta1().Deployments(namespace).Create(&deploy)
deploy := v1.Deployment(*yorcDep)
_, err := clientset.AppsV1().Deployments(namespace).Create(&deploy)
return err
}

func (yorcDep *yorcK8sDeployment) deleteResource(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) error {
deploy := v1beta1.Deployment(*yorcDep)
deploy := v1.Deployment(*yorcDep)
deletePolicy := metav1.DeletePropagationForeground
var gracePeriod int64 = 5
return clientset.ExtensionsV1beta1().Deployments(namespace).Delete(deploy.Name, &metav1.DeleteOptions{
return clientset.AppsV1().Deployments(namespace).Delete(deploy.Name, &metav1.DeleteOptions{
GracePeriodSeconds: &gracePeriod, PropagationPolicy: &deletePolicy})
}

func (yorcDep *yorcK8sDeployment) scaleResource(ctx context.Context, e *execution, clientset kubernetes.Interface, namespace string) error {
deploy := v1beta1.Deployment(*yorcDep)
deploy := v1.Deployment(*yorcDep)
expectedInstances, err := e.getExpectedInstances()
if err != nil {
return err
}
deploy.Spec.Replicas = &expectedInstances

_, err = clientset.ExtensionsV1beta1().Deployments(namespace).Update(&deploy)
_, err = clientset.AppsV1().Deployments(namespace).Update(&deploy)
if err != nil {
return errors.Wrap(err, "failed to scale kubernetes deployment")
}
Expand All @@ -186,7 +186,7 @@ func (yorcDep *yorcK8sDeployment) setAttributes(ctx context.Context, e *executio
}

func (yorcDep *yorcK8sDeployment) isSuccessfullyDeployed(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) (bool, error) {
dep, err := clientset.ExtensionsV1beta1().Deployments(namespace).Get(yorcDep.Name, metav1.GetOptions{})
dep, err := clientset.AppsV1().Deployments(namespace).Get(yorcDep.Name, metav1.GetOptions{})
if err != nil {
return false, err
}
Expand All @@ -206,7 +206,7 @@ func (yorcDep *yorcK8sDeployment) isSuccessfullyDeployed(ctx context.Context, de
}

func (yorcDep *yorcK8sDeployment) isSuccessfullyDeleted(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) (bool, error) {
_, err := clientset.ExtensionsV1beta1().Deployments(namespace).Get(yorcDep.Name, metav1.GetOptions{})
_, err := clientset.AppsV1().Deployments(namespace).Get(yorcDep.Name, metav1.GetOptions{})
if err != nil {
if k8serrors.IsNotFound(err) {
return true, nil
Expand All @@ -221,12 +221,12 @@ func (yorcDep *yorcK8sDeployment) String() string {
}

func (yorcDep *yorcK8sDeployment) getObjectRuntime() runtime.Object {
deploy := v1beta1.Deployment(*yorcDep)
deploy := v1.Deployment(*yorcDep)
return &deploy
}

func (yorcDep *yorcK8sDeployment) streamLogs(ctx context.Context, deploymentID string, clientset kubernetes.Interface) {
deploy := v1beta1.Deployment(*yorcDep)
deploy := v1.Deployment(*yorcDep)
streamDeploymentLogs(ctx, deploymentID, clientset, &deploy)
}

Expand Down Expand Up @@ -254,28 +254,28 @@ func (yorcSts *yorcK8sStatefulSet) getObjectMeta() metav1.ObjectMeta {
}

func (yorcSts *yorcK8sStatefulSet) createResource(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) error {
sts := appsv1.StatefulSet(*yorcSts)
_, err := clientset.AppsV1beta1().StatefulSets(namespace).Create(&sts)
sts := v1.StatefulSet(*yorcSts)
_, err := clientset.AppsV1().StatefulSets(namespace).Create(&sts)
return err
}

func (yorcSts *yorcK8sStatefulSet) deleteResource(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) error {
sts := appsv1.StatefulSet(*yorcSts)
sts := v1.StatefulSet(*yorcSts)
deletePolicy := metav1.DeletePropagationForeground
var gracePeriod int64 = 5
return clientset.AppsV1beta1().StatefulSets(namespace).Delete(sts.Name, &metav1.DeleteOptions{
return clientset.AppsV1().StatefulSets(namespace).Delete(sts.Name, &metav1.DeleteOptions{
GracePeriodSeconds: &gracePeriod, PropagationPolicy: &deletePolicy})
}

func (yorcSts *yorcK8sStatefulSet) scaleResource(ctx context.Context, e *execution, clientset kubernetes.Interface, namespace string) error {
sts := appsv1.StatefulSet(*yorcSts)
sts := v1.StatefulSet(*yorcSts)
expectedInstances, err := e.getExpectedInstances()
if err != nil {
return err
}
sts.Spec.Replicas = &expectedInstances

_, err = clientset.AppsV1beta1().StatefulSets(namespace).Update(&sts)
_, err = clientset.AppsV1().StatefulSets(namespace).Update(&sts)
if err != nil {
return errors.Wrap(err, "failed to scale kubernetes statefulset")
}
Expand All @@ -287,7 +287,7 @@ func (yorcSts *yorcK8sStatefulSet) setAttributes(ctx context.Context, e *executi
}

func (yorcSts *yorcK8sStatefulSet) isSuccessfullyDeployed(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) (bool, error) {
stfs, err := clientset.AppsV1beta1().StatefulSets(namespace).Get(yorcSts.Name, metav1.GetOptions{})
stfs, err := clientset.AppsV1().StatefulSets(namespace).Get(yorcSts.Name, metav1.GetOptions{})
if err != nil {
return false, err
}
Expand All @@ -301,7 +301,7 @@ func (yorcSts *yorcK8sStatefulSet) isSuccessfullyDeployed(ctx context.Context, d
}

func (yorcSts *yorcK8sStatefulSet) isSuccessfullyDeleted(ctx context.Context, deploymentID string, clientset kubernetes.Interface, namespace string) (bool, error) {
_, err := clientset.AppsV1beta1().StatefulSets(namespace).Get(yorcSts.Name, metav1.GetOptions{})
_, err := clientset.AppsV1().StatefulSets(namespace).Get(yorcSts.Name, metav1.GetOptions{})
if err != nil {
if k8serrors.IsNotFound(err) {
return true, nil
Expand All @@ -316,7 +316,7 @@ func (yorcSts *yorcK8sStatefulSet) String() string {
}

func (yorcSts *yorcK8sStatefulSet) getObjectRuntime() runtime.Object {
sts := appsv1.StatefulSet(*yorcSts)
sts := v1.StatefulSet(*yorcSts)
return &sts
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ node_types:
apiVersion:
type: string
description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources"
default: "apps/v1beta1"
default: "apps/v1"
kind:
type: string
description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds"
Expand Down Expand Up @@ -1245,10 +1245,10 @@ node_types:
inputs:
KUBE_DEPLOYMENT_ID: { get_attribute: [SELF, deployment_id] }
NAMESPACE: { get_property: [SELF, namespace] }
EXPECTED_INSTANCES:
EXPECTED_INSTANCES:
type: integer

INSTANCES_DELTA:
INSTANCES_DELTA:
type: integer

implementation: scripts/kubectl_deployment_scale.sh
Expand Down

0 comments on commit 45402f9

Please sign in to comment.