Skip to content

Commit

Permalink
Update V4.2.0 user guide
Browse files Browse the repository at this point in the history
  • Loading branch information
ws410 committed Oct 7, 2023
1 parent 0f7a0a4 commit 8829efb
Show file tree
Hide file tree
Showing 164 changed files with 8,285 additions and 1,061 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

[Releases](https://github.com/Huawei/eSDK_K8S_Plugin/releases)

## Changes since v4.1.0

- Support OpenShift 4.13
- Support Centos 8.4 X86_64
- Support Rocky Linux 8.6 X86_64
- Support EulerOS V2R11 X86_64
- Support k8s 1.16 and 1.27
- Support configuring the timeout for executing commands
- Support create volume snapshot for Hyper-Metro

## Changes since v4.0.0

**Enhancements**
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ COPY_FILE:
mkdir -p ./${PACKAGE}/helm/
cp -r ./helm/* ./${PACKAGE}/helm/

mkdir -p ./${PACKAGE}/manual/
cp -r ./manual/* ./${PACKAGE}/manual/
cp -r ./helm/esdk/crds ./${PACKAGE}/manual/esdk/crds

mkdir -p ./${PACKAGE}/tools
cp -r ./tools/imageUpload/* ./${PACKAGE}/tools

Expand Down
35 changes: 34 additions & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
# 4.2.0

## Supported Huawei storage products

| Storage Product | Version |
| ------------------- |-------------------------------------------------|
| OceanStor Dorado V6 | 6.0.0, 6.0.1, 6.1.0, 6.1.2, 6.1.3, 6.1.5, 6.1.6 |
| OceanStor Dorado V3 | V300R002 |
| OceanStor V6 | 6.1.3, 6.1.5, 6.1.6 |
| OceanStor V5/F V5 | V500R007, V500R007 Kunpeng |
| OceanStor V3/F V3 | V300R006 |
| FusionStorage | V100R006C30 |
| FusionStorage Block | 8.0.0, 8.0.1 |
| OceanStor Pacific | 8.1.0, 8.1.1, 8.1.2, 8.1.3, 8.1.5 |

## Supported container platforms and operating systems (OSs)

| Container platform/OS | Version |
|-----------------------|----------------------------------------------------------------------------------------------------|
| Kubernetes | 1.16, 1.18 - 1.27 |
| Red Hat OpenShift | 4.6 EUS, 4.7, 4.8, 4.9, 4.10, 4.11, 4.12, 4.13 |
| Tanzu Kubernetes | TKGI 1.14.1, TKGI 1.15, TKGI 1.16 |
| CCE Agile | 22.3.2 |
| CentOS | 7.6 x86_64, 7.7 x86_64, 7.9 x86_64, 8.2 x86_64, 8.4 x86_64 |
| Rocky Linux | 8.6 x86_64 |
| SUSE | 15 SP2 x86_64, 15 SP3 x86_64, |
| Red Hat CoreOS | 4.6 x86_64, 4.7 x86_64, 4.8 x86_64, 4.9 x86_64, 4.10 x86_64, 4.11 x86_64, 4.12 x86_64, 4.13 x86_64 |
| Ubuntu | 18.04 x86_64, 20.04 x86_64, 22.04 x86_64 |
| Kylin | V10 SP1 Arm/x86_64, V10 SP2 Arm/x86_64, 7.6 x86_64 |
| Debian | 11 x86_64, 9 x86_64 |
| EulerOS | v2R9 x86_64, V2R10 Arm/x86_64, V2R11 x86_64 |


# 4.1.0

## Supported Huawei storage products
Expand All @@ -18,7 +51,7 @@
| Container platform/OS | Version |
|-----------------------|--------------------------------------------------------------------------|
| Kubernetes | 1.18 - 1.26 |
| Red Hat OpenShift | 4.6 EUS, 4.7, 4.8, 4.9, 4.10, 4.11, 1.12 |
| Red Hat OpenShift | 4.6 EUS, 4.7, 4.8, 4.9, 4.10, 4.11, 4.12 |
| Tanzu Kubernetes | TKGI 1.14.1 |
| CCE Agile | 22.3.2 |
| CentOS | 7.6 x86_64, 7.7 x86_64, 7.9 x86_64, 8.2 x86_64 |
Expand Down
32 changes: 32 additions & 0 deletions cli/client/client_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package client

import (
"context"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -155,3 +156,34 @@ func safeToArray[T any](t T) []T {
}
return []T{t}
}

func getObjectType(object interface{}) ObjectType {
switch object.(type) {
case *corev1.Namespace, *corev1.NamespaceList:
return Namespace
case *corev1.Node, *corev1.NodeList:
return Node
case *corev1.Pod, *corev1.PodList:
return Pod
default:
return Unknown
}
}

func (r *CommonCallHandler[T]) CheckObjectExist(ctx context.Context, namespace, nodeName,
objectName string) (bool, error) {
var object, empty T
err := r.client.GetObject(ctx, getObjectType(&object), namespace, nodeName, JSON, &object, objectName)
if err != nil {
return false, err
}

return !reflect.DeepEqual(object, empty), nil
}

func (r *CommonCallHandler[T]) GetObject(ctx context.Context, namespace, nodeName string,
objectName ...string) (T, error) {
var object T
err := r.client.GetObject(ctx, getObjectType(&object), namespace, nodeName, JSON, &object, objectName...)
return object, err
}
175 changes: 175 additions & 0 deletions cli/client/client_helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package client

import (
"context"
"errors"
"reflect"
"testing"

"github.com/agiledragon/gomonkey/v2"
"github.com/smartystreets/goconvey/convey"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestGetObjectType_get_namespace_type(t *testing.T) {
// arrange
var mockObject corev1.Namespace
var except = Namespace
convey.Convey("test get_namespace_type", t, func() {
// action
objectType := getObjectType(&mockObject)
// assert
convey.So(objectType, convey.ShouldResemble, except)
})
}

func TestGetObjectType_get_node_type(t *testing.T) {
// arrange
var mockObject corev1.NodeList
var except = Node
convey.Convey("test get_node_type", t, func() {
// action
objectType := getObjectType(&mockObject)
// assert
convey.So(objectType, convey.ShouldResemble, except)
})
}

func TestGetObjectType_get_pod_type(t *testing.T) {
// arrange
var mockObject corev1.Pod
var except = Pod
convey.Convey("test get_pod_type", t, func() {
// action
objectType := getObjectType(&mockObject)
// assert
convey.So(objectType, convey.ShouldResemble, except)
})
}

func TestGetObjectType_get_unknown_type(t *testing.T) {
// arrange
var mockObject interface{}
var except = Unknown
convey.Convey("test get_unknown_type", t, func() {
// action
objectType := getObjectType(&mockObject)
// assert
convey.So(objectType, convey.ShouldResemble, except)
})
}

func TestCommonCallHandler_CheckObjectExist_check_exist_namespace(t *testing.T) {
// arrange
var mockNamespace, mockNodeName, mockObjectName = IgnoreNamespace, IgnoreNode, "namespace"
var mockCli = NewCommonCallHandler[corev1.Namespace](&KubernetesCLI{})
var except = true
// mock
patches := gomonkey.ApplyMethod(reflect.TypeOf(&KubernetesCLI{}), "GetObject",
func(cli *KubernetesCLI, ctx context.Context, objectType ObjectType, namespace string, nodeName string,
outputType OutputType, data interface{}, objectName ...string) error {
if objectType == Namespace && namespace == mockNamespace && nodeName == mockNodeName &&
outputType == JSON && objectName[0] == mockObjectName {
if ns, ok := data.(*corev1.Namespace); ok {
*ns = corev1.Namespace{}
(*ns).Name = mockObjectName
}
return nil
}
return errors.New("")
})
defer patches.Reset()

convey.Convey("test check_exist_namespace", t, func() {
// action
exist, err := mockCli.CheckObjectExist(context.Background(), mockNamespace, mockNodeName, mockObjectName)
// assert
convey.So(exist, convey.ShouldResemble, except)
convey.So(err, convey.ShouldBeNil)
})
}

func TestCommonCallHandler_CheckObjectExist_check_not_exist_node(t *testing.T) {
// arrange
var mockNamespace, mockNodeName, mockObjectName = IgnoreNamespace, IgnoreNode, "node"
var mockCli = NewCommonCallHandler[corev1.Node](&KubernetesCLI{})
var except = false
// mock
patches := gomonkey.ApplyMethod(reflect.TypeOf(&KubernetesCLI{}), "GetObject",
func(cli *KubernetesCLI, ctx context.Context, objectType ObjectType, namespace string, nodeName string,
outputType OutputType, data interface{}, objectName ...string) error {
if objectType == Node && namespace == mockNamespace && nodeName == mockNodeName &&
outputType == JSON && objectName[0] == mockObjectName {
return nil
}
return errors.New("")
})
defer patches.Reset()

convey.Convey("test check_not_exist_node", t, func() {
// action
exist, err := mockCli.CheckObjectExist(context.Background(), mockNamespace, mockNodeName, mockObjectName)
// assert
convey.So(exist, convey.ShouldResemble, except)
convey.So(err, convey.ShouldBeNil)
})
}

func TestCommonCallHandler_GetObject_get_podList(t *testing.T) {
// arrange
var mockNamespace, mockNodeName = "namespace", IgnoreNode
var mockCli = NewCommonCallHandler[corev1.PodList](&KubernetesCLI{})
var except = corev1.PodList{
Items: []corev1.Pod{
{
ObjectMeta: v1.ObjectMeta{
Name: "pod1",
},
},
{
ObjectMeta: v1.ObjectMeta{
Name: "pod2",
},
},
},
}
// mock
patches := gomonkey.ApplyMethod(reflect.TypeOf(&KubernetesCLI{}), "GetObject",
func(cli *KubernetesCLI, ctx context.Context, objectType ObjectType, namespace string, nodeName string,
outputType OutputType, data interface{}, objectName ...string) error {
if objectType == Pod && namespace == mockNamespace && nodeName == mockNodeName &&
outputType == JSON && objectName == nil {
if podList, ok := data.(*corev1.PodList); ok {
*podList = except
}
return nil
}
return errors.New("")
})
defer patches.Reset()

convey.Convey("test get pod list", t, func() {
// action
object, err := mockCli.GetObject(context.Background(), mockNamespace, mockNodeName)
// assert
convey.So(object, convey.ShouldResemble, except)
convey.So(err, convey.ShouldBeNil)
})
}
43 changes: 43 additions & 0 deletions cli/client/kube_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package client

import (
"context"
"encoding/json"
"fmt"

Expand Down Expand Up @@ -125,3 +126,45 @@ func (k *KubernetesCLI) GetNameSpace() (string, error) {
namespace := serviceAccount.ObjectMeta.Namespace
return namespace, nil
}

// GetObject used to get the specified format data of the object with specified conditions and unmarshal to the data.
func (k *KubernetesCLI) GetObject(ctx context.Context, objectType ObjectType, namespace, nodeName string,
outputType OutputType, data interface{}, objectName ...string) error {
return NewKubernetesCLIArgs(k.CLI()).
SelectObject(objectType, objectName...).
WithSpecifiedNamespace(namespace).
WithSpecifiedNode(nodeName).
WithOutPutFormat(outputType).
Get(ctx, &data)
}

// ExecCmdInSpecifiedContainer used to executes the specified command in the container with specified conditions.
func (k *KubernetesCLI) ExecCmdInSpecifiedContainer(ctx context.Context, namespace, containerName, cmd string,
podName ...string) ([]byte, error) {
return NewKubernetesCLIArgs(k.CLI()).
SelectObject(Pod, podName...).
WithSpecifiedNamespace(namespace).
WithSpecifiedContainer(containerName).
Exec(ctx, cmd)
}

// CopyContainerFileToLocal used to copying a Local File to a Container with Specified Conditions
func (k *KubernetesCLI) CopyContainerFileToLocal(ctx context.Context, namespace, containerName, src, dst string,
podName ...string) ([]byte, error) {
return NewKubernetesCLIArgs(k.CLI()).
SelectObject(Pod, podName...).
WithSpecifiedNamespace(namespace).
WithSpecifiedContainer(containerName).
Copy(ctx, src, dst, ContainerToLocal)
}

// GetConsoleLogs used to get the console logs of a specified container.
func (k *KubernetesCLI) GetConsoleLogs(ctx context.Context, namespace, containerName string, isHistoryLogs bool,
podName ...string) ([]byte, error) {
return NewKubernetesCLIArgs(k.CLI()).
SelectObject(Pod, podName...).
WithSpecifiedNamespace(namespace).
WithSpecifiedContainer(containerName).
WithHistoryLogs(isHistoryLogs).
Logs(ctx)
}
Loading

0 comments on commit 8829efb

Please sign in to comment.