mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-18 04:18:18 +00:00
Compare commits
10 Commits
cmd/resour
...
api/v0.3.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c9a3756b4 | ||
|
|
3f417c7b5b | ||
|
|
4526cb14e8 | ||
|
|
595e41a3ec | ||
|
|
118ba7eefe | ||
|
|
488bc5aceb | ||
|
|
2786287444 | ||
|
|
4e7446540c | ||
|
|
90ecc5d30a | ||
|
|
7b1a5f85ed |
@@ -4,7 +4,6 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/spf13/cobra v0.0.5
|
||||
k8s.io/api v0.17.0
|
||||
k8s.io/apimachinery v0.17.0
|
||||
k8s.io/cli-runtime v0.17.0
|
||||
k8s.io/client-go v0.17.0
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
package kubectlcobra
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
)
|
||||
@@ -57,3 +60,86 @@ func sortGroupingObject(infos []*resource.Info) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Adds the inventory of all objects (passed as infos) to the
|
||||
// grouping object. Returns an error if a grouping object does not
|
||||
// exist, or we are unable to successfully add the inventory to
|
||||
// the grouping object; nil otherwise. Each object is in
|
||||
// unstructured.Unstructured format.
|
||||
func addInventoryToGroupingObj(infos []*resource.Info) error {
|
||||
|
||||
// Iterate through the objects (infos), creating an Inventory struct
|
||||
// as metadata for the object, or if it's the grouping object, store it.
|
||||
var groupingObj *unstructured.Unstructured
|
||||
inventoryMap := map[string]string{}
|
||||
for _, info := range infos {
|
||||
obj := info.Object
|
||||
if isGroupingObject(obj) {
|
||||
// If we have more than one grouping object--error.
|
||||
if groupingObj != nil {
|
||||
return fmt.Errorf("Error--applying more than one grouping object.")
|
||||
}
|
||||
var ok bool
|
||||
groupingObj, ok = obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("Grouping object is not an Unstructured: %#v", groupingObj)
|
||||
}
|
||||
} else {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Creating inventory; object is nil")
|
||||
}
|
||||
gk := obj.GetObjectKind().GroupVersionKind().GroupKind()
|
||||
inventory, err := createInventory(info.Namespace, info.Name, gk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
inventoryMap[inventory.String()] = ""
|
||||
}
|
||||
}
|
||||
|
||||
// If we've found the grouping object, store the object metadata inventory
|
||||
// in the grouping config map.
|
||||
if groupingObj == nil {
|
||||
return fmt.Errorf("Grouping object not found")
|
||||
}
|
||||
err := unstructured.SetNestedStringMap(groupingObj.UnstructuredContent(), inventoryMap, "data")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// retrieveInventoryFromGroupingObj returns a slice of pointers to the
|
||||
// inventory metadata. This function finds the grouping object, then
|
||||
// parses the stored resource metadata into Inventory structs. Returns
|
||||
// an error if there is a problem parsing the data into Inventory
|
||||
// structs, or if the grouping object is not in Unstructured format; nil
|
||||
// otherwise. If a grouping object does not exist, or it does not have a
|
||||
// "data" map, then returns an empty slice and no error.
|
||||
func retrieveInventoryFromGroupingObj(infos []*resource.Info) ([]*Inventory, error) {
|
||||
inventory := []*Inventory{}
|
||||
groupingInfo, exists := findGroupingObject(infos)
|
||||
if exists {
|
||||
groupingObj, ok := groupingInfo.Object.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
err := fmt.Errorf("Grouping object is not an Unstructured: %#v", groupingObj)
|
||||
return inventory, err
|
||||
}
|
||||
invMap, exists, err := unstructured.NestedStringMap(groupingObj.Object, "data")
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error retrieving inventory from grouping object.")
|
||||
return inventory, err
|
||||
}
|
||||
if exists {
|
||||
for invStr := range invMap {
|
||||
inv, err := parseInventory(invStr)
|
||||
if err != nil {
|
||||
return inventory, err
|
||||
}
|
||||
inventory = append(inventory, inv)
|
||||
}
|
||||
}
|
||||
}
|
||||
return inventory, nil
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ package kubectlcobra
|
||||
import (
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
)
|
||||
|
||||
@@ -19,12 +19,16 @@ var pod1Name = "pod-1"
|
||||
var pod2Name = "pod-2"
|
||||
var pod3Name = "pod-3"
|
||||
|
||||
var groupingObj = corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: testNamespace,
|
||||
Name: groupingObjName,
|
||||
Labels: map[string]string{
|
||||
GroupingLabel: "true",
|
||||
var groupingObj = unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": groupingObjName,
|
||||
"namespace": testNamespace,
|
||||
"labels": map[string]interface{}{
|
||||
GroupingLabel: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -35,10 +39,14 @@ var groupingInfo = &resource.Info{
|
||||
Object: &groupingObj,
|
||||
}
|
||||
|
||||
var pod1 = corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: testNamespace,
|
||||
Name: pod1Name,
|
||||
var pod1 = unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": pod1Name,
|
||||
"namespace": testNamespace,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -48,10 +56,14 @@ var pod1Info = &resource.Info{
|
||||
Object: &pod1,
|
||||
}
|
||||
|
||||
var pod2 = corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: testNamespace,
|
||||
Name: pod2Name,
|
||||
var pod2 = unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": pod2Name,
|
||||
"namespace": testNamespace,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -61,10 +73,14 @@ var pod2Info = &resource.Info{
|
||||
Object: &pod2,
|
||||
}
|
||||
|
||||
var pod3 = corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: testNamespace,
|
||||
Name: pod3Name,
|
||||
var pod3 = unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": pod3Name,
|
||||
"namespace": testNamespace,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -215,3 +231,190 @@ func TestSortGroupingObject(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddRetrieveInventoryToFromGroupingObject(t *testing.T) {
|
||||
tests := []struct {
|
||||
infos []*resource.Info
|
||||
expected []*Inventory
|
||||
isError bool
|
||||
}{
|
||||
// No grouping object is an error.
|
||||
{
|
||||
infos: []*resource.Info{},
|
||||
isError: true,
|
||||
},
|
||||
// No grouping object is an error.
|
||||
{
|
||||
infos: []*resource.Info{pod1Info, pod2Info},
|
||||
isError: true,
|
||||
},
|
||||
// Grouping object without other objects is OK.
|
||||
{
|
||||
infos: []*resource.Info{groupingInfo},
|
||||
expected: []*Inventory{},
|
||||
isError: false,
|
||||
},
|
||||
// More than one grouping object is an error.
|
||||
{
|
||||
infos: []*resource.Info{groupingInfo, groupingInfo},
|
||||
expected: []*Inventory{},
|
||||
isError: true,
|
||||
},
|
||||
// More than one grouping object is an error.
|
||||
{
|
||||
infos: []*resource.Info{groupingInfo, pod1Info, groupingInfo},
|
||||
expected: []*Inventory{},
|
||||
isError: true,
|
||||
},
|
||||
{
|
||||
infos: []*resource.Info{groupingInfo, pod1Info},
|
||||
expected: []*Inventory{
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod1Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
infos: []*resource.Info{pod1Info, groupingInfo},
|
||||
expected: []*Inventory{
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod1Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
infos: []*resource.Info{pod1Info, pod2Info, groupingInfo, pod3Info},
|
||||
expected: []*Inventory{
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod1Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod2Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod3Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
infos: []*resource.Info{pod1Info, pod2Info, pod3Info, groupingInfo},
|
||||
expected: []*Inventory{
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod1Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod2Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod3Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
infos: []*resource.Info{groupingInfo, pod1Info, pod2Info, pod3Info},
|
||||
expected: []*Inventory{
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod1Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod2Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
&Inventory{
|
||||
Namespace: testNamespace,
|
||||
Name: pod3Name,
|
||||
GroupKind: schema.GroupKind{
|
||||
Group: "",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
isError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := addInventoryToGroupingObj(test.infos)
|
||||
if test.isError && err == nil {
|
||||
t.Errorf("Should have produced an error, but returned none.")
|
||||
}
|
||||
if !test.isError {
|
||||
if err != nil {
|
||||
t.Errorf("Received error when expecting none (%s)\n", err)
|
||||
} else {
|
||||
retrieved, err := retrieveInventoryFromGroupingObj(test.infos)
|
||||
if err != nil {
|
||||
t.Errorf("Error retrieving inventory: %s\n", err)
|
||||
}
|
||||
if len(test.expected) != len(retrieved) {
|
||||
t.Errorf("Expected inventory for %d resources, actual %d",
|
||||
len(test.expected), len(retrieved))
|
||||
}
|
||||
for _, expected := range test.expected {
|
||||
found := false
|
||||
for _, actual := range retrieved {
|
||||
if expected.Equals(actual) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected inventory (%s) not found", expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
cmd/resource/fixgomod.sh
Executable file
20
cmd/resource/fixgomod.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2019 The Kubernetes Authors.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -e
|
||||
|
||||
: "${kyaml_major?Need to source VERSIONS}"
|
||||
: "${kyaml_minor?Need to source VERSIONS}"
|
||||
: "${kyaml_patch?Need to source VERSIONS}"
|
||||
|
||||
: "${kstatus_major?Need to source VERSIONS}"
|
||||
: "${kstatus_minor?Need to source VERSIONS}"
|
||||
: "${kstatus_patch?Need to source VERSIONS}"
|
||||
|
||||
|
||||
go mod edit -dropreplace=sigs.k8s.io/kustomize/kyaml@v0.0.0
|
||||
go mod edit -require=sigs.k8s.io/kustomize/kyaml@v$kyaml_major.$kyaml_minor.$kyaml_patch
|
||||
|
||||
go mod edit -dropreplace=sigs.k8s.io/kustomize/kstatus@v0.0.0
|
||||
go mod edit -require=sigs.k8s.io/kustomize/kstatus@v$kstatus_major.$kstatus_minor.$kstatus_patch
|
||||
@@ -12,11 +12,11 @@ require (
|
||||
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655
|
||||
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90
|
||||
sigs.k8s.io/controller-runtime v0.4.0
|
||||
sigs.k8s.io/kustomize/kstatus v0.0.0-20191204200457-7c1b477ff62d
|
||||
sigs.k8s.io/kustomize/kyaml v0.0.0-20191202204815-0a19a5dbd9b8
|
||||
sigs.k8s.io/kustomize/kstatus v0.0.0
|
||||
sigs.k8s.io/kustomize/kyaml v0.0.0
|
||||
)
|
||||
|
||||
replace (
|
||||
sigs.k8s.io/kustomize/kstatus v0.0.0-20191204200457-7c1b477ff62d => ../../kstatus
|
||||
sigs.k8s.io/kustomize/kyaml v0.0.0-20191202204815-0a19a5dbd9b8 => ../../kyaml
|
||||
sigs.k8s.io/kustomize/kstatus v0.0.0 => ../../kstatus
|
||||
sigs.k8s.io/kustomize/kyaml v0.0.0 => ../../kyaml
|
||||
)
|
||||
|
||||
@@ -138,10 +138,10 @@ func (s *TablePrinter) Print() {
|
||||
|
||||
func (s *TablePrinter) PrintUntil(stop <-chan struct{}, interval time.Duration) <-chan struct{} {
|
||||
completed := make(chan struct{})
|
||||
setColor(s.out, WHITE)
|
||||
s.printTable(s.statusInfo.CurrentStatus(), false)
|
||||
go func() {
|
||||
defer close(completed)
|
||||
setColor(s.out, WHITE)
|
||||
s.printTable(s.statusInfo.CurrentStatus(), false)
|
||||
ticker := time.NewTicker(interval)
|
||||
for {
|
||||
select {
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestWaitNoResources(t *testing.T) {
|
||||
|
||||
aggStatuses := tableOutput.allAggStatuses()
|
||||
expectedAggStatuses := []status.Status{
|
||||
status.CurrentStatus,
|
||||
status.UnknownStatus,
|
||||
status.CurrentStatus,
|
||||
}
|
||||
if !reflect.DeepEqual(aggStatuses, expectedAggStatuses) {
|
||||
|
||||
@@ -1,27 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# VERSIONS contains the release versions of each kustomize go module
|
||||
# update this file and run releaseall.sh to cut a new release
|
||||
# update this file and run releasemodule.sh to cut a new release
|
||||
|
||||
# kyaml version
|
||||
export kyaml_major=0
|
||||
export kyaml_minor=0
|
||||
export kyaml_patch=5
|
||||
export kyaml_patch=6
|
||||
|
||||
# kstatus version
|
||||
export kstatus_major=0
|
||||
export kstatus_minor=0
|
||||
export kstatus_patch=1
|
||||
|
||||
# kustomize api version
|
||||
export api_major=0
|
||||
export api_minor=3
|
||||
export api_patch=1
|
||||
export api_patch=2
|
||||
|
||||
# cmd/config version
|
||||
export cmd_config_major=0
|
||||
export cmd_config_minor=0
|
||||
export cmd_config_patch=5
|
||||
export cmd_config_patch=6
|
||||
|
||||
# cmd/kubectl version
|
||||
export cmd_kubectl_major=0
|
||||
export cmd_kubectl_minor=0
|
||||
export cmd_kubectl_patch=2
|
||||
export cmd_kubectl_patch=3
|
||||
|
||||
# cmd/resource version
|
||||
export cmd_resource_major=0
|
||||
export cmd_resource_minor=0
|
||||
export cmd_resource_patch=1
|
||||
|
||||
# kustomize version
|
||||
export kustomize_major=3
|
||||
|
||||
@@ -67,7 +67,7 @@ function releaseModule {
|
||||
echo "$module complete"
|
||||
}
|
||||
|
||||
modules="kyaml api cmd/config cmd/kubectl pluginator kustomize"
|
||||
modules="kyaml api kstatus cmd/config cmd/resource cmd/kubectl pluginator kustomize"
|
||||
|
||||
# configure the branch and tag names
|
||||
module="${1?must provide the module to release as an argument: supported modules [$modules]}"
|
||||
|
||||
Reference in New Issue
Block a user