Repository: kubernetes/klog
Pull request #249 (2021-07-01 09:50:29)

Implement KObjs function to handle slice of KMetada
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. If this is your first time, read our contributor guidelines https://git.k8s.io/community/contributors/guide/pull-requests.md#the-pull-request-submit-process and developer guide https://git.k8s.io/community/contributors/devel/development.md#development-guide
2. If you want *faster* PR reviews, read how: https://git.k8s.io/community/contributors/guide/pull-requests.md#best-practices-for-faster-reviews
3. Follow the instructions for writing a release note: https://git.k8s.io/community/contributors/guide/release-notes.md
4. If the PR is unfinished, see how to mark it: https://git.k8s.io/community/contributors/guide/pull-requests.md#marking-unfinished-pull-requests
5. If this PR changes image versions, please title this PR "Bump <image name> from x.x.x to y.y.y."
-->

**What this PR does / why we need it**:
As discussion here https://github.com/kubernetes/kubernetes/pull/99029#discussion_r586816580, implement KObjs function to handle slice of KMetada in klog pkg.
**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Refs https://github.com/kubernetes/kubernetes/issues/102434

**Special notes for your reviewer**:

_Please confirm that if this PR changes any image versions, then that's the sole change this PR makes._

**Release note**:
<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR requires additional action from users switching to the new release, include the string "action required".
2. If no release note is required, just write "NONE".
-->
```release-note
Implement KObjs function to handle slice of KMetada
```
/cc @serathius @DirectXMan12 

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes/klog/pull/249#" title="Author self-approved">yuzhiquan</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **lavalamp** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @lavalamp` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes%2Fklog).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes/klog/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["lavalamp"]} -->
serathius: /lgtm
serathius: /assign @dims 
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes/klog/pull/249#issuecomment-872171956" title="LGTM">serathius</a>*, *<a href="https://github.com/kubernetes/klog/pull/249#" title="Author self-approved">yuzhiquan</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **lavalamp** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @lavalamp` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes%2Fklog).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes/klog/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["lavalamp"]} -->

Patch:
diff --git a/klog.go b/klog.go
index 1e187f7..d24087d 100644
--- a/klog.go
+++ b/klog.go
@@ -1603,3 +1603,20 @@ func KRef(namespace, name string) ObjectRef {
 		Namespace: namespace,
 	}
 }
+
+// KObjs returns slice of ObjectRef from an slice of ObjectMeta
+func KObjs(arg interface{}) []ObjectRef {
+	s := reflect.ValueOf(arg)
+	if s.Kind() != reflect.Slice {
+		return nil
+	}
+	objectRefs := make([]ObjectRef, 0, s.Len())
+	for i := 0; i < s.Len(); i++ {
+		if v, ok := s.Index(i).Interface().(KMetadata); ok {
+			objectRefs = append(objectRefs, KObj(v))
+		} else {
+			return nil
+		}
+	}
+	return objectRefs
+}


Test patch:
diff --git a/klog_test.go b/klog_test.go
index cd67e4c..7f6a647 100644
--- a/klog_test.go
+++ b/klog_test.go
@@ -1754,3 +1754,81 @@ func TestKlogFlagPrefix(t *testing.T) {
 		}
 	})
 }
+
+func TestKObjs(t *testing.T) {
+	tests := []struct {
+		name string
+		obj  interface{}
+		want []ObjectRef
+	}{
+		{
+			name: "test for KObjs function with KMetadata slice",
+			obj: []kMetadataMock{
+				{
+					name: "kube-dns",
+					ns:   "kube-system",
+				},
+				{
+					name: "mi-conf",
+				},
+				{},
+			},
+			want: []ObjectRef{
+				{
+					Name:      "kube-dns",
+					Namespace: "kube-system",
+				},
+				{
+					Name: "mi-conf",
+				},
+				{},
+			},
+		},
+		{
+			name: "test for KObjs function with KMetadata pointer slice",
+			obj: []*kMetadataMock{
+				{
+					name: "kube-dns",
+					ns:   "kube-system",
+				},
+				{
+					name: "mi-conf",
+				},
+				nil,
+			},
+			want: []ObjectRef{
+				{
+					Name:      "kube-dns",
+					Namespace: "kube-system",
+				},
+				{
+					Name: "mi-conf",
+				},
+				{},
+			},
+		},
+		{
+			name: "test for KObjs function with slice does not implement KMetadata",
+			obj:  []int{1, 2, 3, 4, 6},
+			want: nil,
+		},
+		{
+			name: "test for KObjs function with interface",
+			obj:  "test case",
+			want: nil,
+		},
+		{
+			name: "test for KObjs function with nil",
+			obj:  nil,
+			want: nil,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if !reflect.DeepEqual(KObjs(tt.obj), tt.want) {
+				t.Errorf("\nwant:\t %v\n got:\t %v", tt.want, KObjs(tt.obj))
+			}
+		})
+	}
+}