Add manifestreader interface implementation
This implementation would allow to use bundle as source of manifests for cli-utils applier, and will also eliminate the need to dump manifests to the filesystem Change-Id: I37f21beaaf4cb2800b50d4ccb18596a4c09ea19b
This commit is contained in:
parent
821d02eba4
commit
1cafd674df
19
pkg/k8s/utils/testdata/kubeconfig.yaml
vendored
Normal file
19
pkg/k8s/utils/testdata/kubeconfig.yaml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFNU1Ea3lPVEUzTURNd09Wb1hEVEk1TURreU5qRTNNRE13T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUZyCkdxM0kyb2dZci81Y01Udy9Na1pORTNWQURzdEdyU240WjU2TDhPUGhMcUhDN2t1dno2dVpES3dCSGtGeTBNK2MKRXIzd2piUGE1aTV5NmkyMGtxSHBVMjdPZTA0dzBXV2s4N0RSZVlWaGNoZVJHRXoraWt3SndIcGRmMjJVemZNKwpkSDBzaUhuMVd6UnovYk4za3hMUzJlMnZ2U1Y3bmNubk1YRUd4OXV0MUY0NThHeWxxdmxXTUlWMzg5Q2didXFDCkcwcFdiMTBLM0RVZWdiT25Xa1FmSm5sTWRRVVZDUVdZZEZaaklrcWtkWi9hVTRobkNEV01oZXNWRnFNaDN3VVAKczhQay9BNWh1ZFFPbnFRNDVIWXZLdjZ5RjJWcDUyWExBRUx3NDJ4aVRKZlh0V1h4eHR6cU4wY1lyL2VxeS9XMQp1YVVGSW5xQjFVM0JFL1oxbmFrQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKUUVKQVBLSkFjVDVuK3dsWGJsdU9mS0J3c2gKZTI4R1c5R2QwM0N0NGF3RzhzMXE1ZHNua2tpZmVTUENHVFZ1SXF6UTZDNmJaSk9SMDMvVEl5ejh6NDJnaitDVApjWUZXZkltM2RKTnpRL08xWkdySXZZNWdtcWJtWDlpV0JaU24rRytEOGxubzd2aGMvY0tBRFR5OTMvVU92MThuCkdhMnIrRGJJcHcyTWVBVEl2elpxRS9RWlVSQ25DMmdjUFhTVzFqN2h4R3o1a3ZNcGVDZTdQYVUvdVFvblVHSWsKZ2t6ZzI4NHQvREhUUzc4N1V1SUg5cXBaV09yTFNMOGFBeUxQUHhWSXBteGZmbWRETE9TS2VUemRlTmxoSitUMwowQlBVaHBQTlJBNTNJN0hRQjhVUDR2elNONTkzZ1VFbVlFQ2Jic2RYSzB6ZVR6SDdWWHR2Zmd5WTVWWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
server: https://10.0.1.7:6443
|
||||
name: kubernetes_target
|
||||
contexts:
|
||||
- context:
|
||||
cluster: kubernetes_target
|
||||
user: kubernetes-admin
|
||||
name: kubernetes-admin@kubernetes
|
||||
current-context: ""
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: kubernetes-admin
|
||||
user:
|
||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQXhEdzk2RUY4SXN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4T1RBNU1qa3hOekF6TURsYUZ3MHlNREE1TWpneE56QXpNVEphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXV6R0pZdlBaNkRvaTQyMUQKSzhXSmFaQ25OQWQycXo1cC8wNDJvRnpRUGJyQWd6RTJxWVZrek9MOHhBVmVSN1NONXdXb1RXRXlGOEVWN3JyLwo0K0hoSEdpcTVQbXF1SUZ5enpuNi9JWmM4alU5eEVmenZpa2NpckxmVTR2UlhKUXdWd2dBU05sMkFXQUloMmRECmRUcmpCQ2ZpS1dNSHlqMFJiSGFsc0J6T3BnVC9IVHYzR1F6blVRekZLdjJkajVWMU5rUy9ESGp5UlJKK0VMNlEKQlltR3NlZzVQNE5iQzllYnVpcG1NVEFxL0p1bU9vb2QrRmpMMm5acUw2Zkk2ZkJ0RjVPR2xwQ0IxWUo4ZnpDdApHUVFaN0hUSWJkYjJ0cDQzRlZPaHlRYlZjSHFUQTA0UEoxNSswV0F5bVVKVXo4WEE1NDRyL2J2NzRKY0pVUkZoCmFyWmlRd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMMmhIUmVibEl2VHJTMFNmUVg1RG9ueVVhNy84aTg1endVWApSd3dqdzFuS0U0NDJKbWZWRGZ5b0hRYUM4Ti9MQkxyUXM0U0lqU1JYdmFHU1dSQnRnT1RRV21Db1laMXdSbjdwCndDTXZQTERJdHNWWm90SEZpUFl2b1lHWFFUSXA3YlROMmg1OEJaaEZ3d25nWUovT04zeG1rd29IN1IxYmVxWEYKWHF1TTluekhESk41VlZub1lQR09yRHMwWlg1RnNxNGtWVU0wVExNQm9qN1ZIRDhmU0E5RjRYNU4yMldsZnNPMAo4aksrRFJDWTAyaHBrYTZQQ0pQS0lNOEJaMUFSMG9ZakZxT0plcXpPTjBqcnpYWHh4S2pHVFVUb1BldVA5dCtCCjJOMVA1TnI4a2oxM0lrend5Q1NZclFVN09ZM3ltZmJobHkrcXZxaFVFa014MlQ1SkpmQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
||||
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBdXpHSll2UFo2RG9pNDIxREs4V0phWkNuTkFkMnF6NXAvMDQyb0Z6UVBickFnekUyCnFZVmt6T0w4eEFWZVI3U041d1dvVFdFeUY4RVY3cnIvNCtIaEhHaXE1UG1xdUlGeXp6bjYvSVpjOGpVOXhFZnoKdmlrY2lyTGZVNHZSWEpRd1Z3Z0FTTmwyQVdBSWgyZERkVHJqQkNmaUtXTUh5ajBSYkhhbHNCek9wZ1QvSFR2MwpHUXpuVVF6Rkt2MmRqNVYxTmtTL0RIanlSUkorRUw2UUJZbUdzZWc1UDROYkM5ZWJ1aXBtTVRBcS9KdW1Pb29kCitGakwyblpxTDZmSTZmQnRGNU9HbHBDQjFZSjhmekN0R1FRWjdIVEliZGIydHA0M0ZWT2h5UWJWY0hxVEEwNFAKSjE1KzBXQXltVUpVejhYQTU0NHIvYnY3NEpjSlVSRmhhclppUXdJREFRQUJBb0lCQVFDU0pycjlaeVpiQ2dqegpSL3VKMFZEWCt2aVF4c01BTUZyUjJsOE1GV3NBeHk1SFA4Vk4xYmc5djN0YUVGYnI1U3hsa3lVMFJRNjNQU25DCm1uM3ZqZ3dVQWlScllnTEl5MGk0UXF5VFBOU1V4cnpTNHRxTFBjM3EvSDBnM2FrNGZ2cSsrS0JBUUlqQnloamUKbnVFc1JpMjRzT3NESlM2UDE5NGlzUC9yNEpIM1M5bFZGbkVuOGxUR2c0M1kvMFZoMXl0cnkvdDljWjR5ZUNpNwpjMHFEaTZZcXJZaFZhSW9RRW1VQjdsbHRFZkZzb3l4VDR6RTE5U3pVbkRoMmxjYTF1TzhqcmI4d2xHTzBoQ2JyClB1R1l2WFFQa3Q0VlNmalhvdGJ3d2lBNFRCVERCRzU1bHp6MmNKeS9zSS8zSHlYbEMxcTdXUmRuQVhhZ1F0VzkKOE9DZGRkb0JBb0dCQU5NcUNtSW94REtyckhZZFRxT1M1ZFN4cVMxL0NUN3ZYZ0pScXBqd2Y4WHA2WHo0KzIvTAozVXFaVDBEL3dGTkZkc1Z4eFYxMnNYMUdwMHFWZVlKRld5OVlCaHVSWGpTZ0ZEWldSY1Z1Y01sNVpPTmJsbmZGCjVKQ0xnNXFMZ1g5VTNSRnJrR3A0R241UDQxamg4TnhKVlhzZG5xWE9xNTFUK1RRT1UzdkpGQjc1QW9HQkFPTHcKalp1cnZtVkZyTHdaVGgvRDNpWll5SVV0ZUljZ2NKLzlzbTh6L0pPRmRIbFd4dGRHUFVzYVd1MnBTNEhvckFtbgpqTm4vSTluUXd3enZ3MWUzVVFPbUhMRjVBczk4VU5hbk5TQ0xNMW1yaXZHRXJ1VHFnTDM1bU41eFZPdTUxQU5JCm4yNkFtODBJT2JDeEtLa0R0ZXJSaFhHd3g5c1pONVJCbG9VRThZNGJBb0dBQ3ZsdVhMZWRxcng5VkE0bDNoNXUKVDJXRVUxYjgxZ1orcmtRc1I1S0lNWEw4cllBTElUNUpHKzFuendyN3BkaEFXZmFWdVV2SDRhamdYT0h6MUs5aQpFODNSVTNGMG9ldUg0V01PY1RwU0prWm0xZUlXcWRiaEVCb1FGdUlWTXRib1BsV0d4ZUhFRHJoOEtreGp4aThSCmdEcUQyajRwY1IzQ0g5QjJ5a0lqQjVFQ2dZRUExc0xXLys2enE1c1lNSm14K1JXZThhTXJmL3pjQnVTSU1LQWgKY0dNK0wwMG9RSHdDaUU4TVNqcVN1ajV3R214YUFuanhMb3ZwSFlRV1VmUEVaUW95UE1YQ2VhRVBLOU4xbk8xMwp0V2lHRytIZkIxaU5PazFCc0lhNFNDbndOM1FRVTFzeXBaeEgxT3hueS9LYmkvYmEvWEZ5VzNqMGFUK2YvVWxrCmJGV1ZVdWtDZ1lFQTBaMmRTTFlmTjV5eFNtYk5xMWVqZXdWd1BjRzQxR2hQclNUZEJxdHFac1doWGE3aDdLTWEKeHdvamh5SXpnTXNyK2tXODdlajhDQ2h0d21sQ1p5QU92QmdOZytncnJ1cEZLM3FOSkpKeU9YREdHckdpbzZmTQp5aXB3Q2tZVGVxRThpZ1J6UkI5QkdFUGY4eVpjMUtwdmZhUDVhM0lRZmxiV0czbGpUemNNZVZjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
|
2
pkg/k8s/utils/testdata/source_bundle/kustomization.yaml
vendored
Normal file
2
pkg/k8s/utils/testdata/source_bundle/kustomization.yaml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
resources:
|
||||
- replicationcontroller.yaml
|
22
pkg/k8s/utils/testdata/source_bundle/replicationcontroller.yaml
vendored
Normal file
22
pkg/k8s/utils/testdata/source_bundle/replicationcontroller.yaml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: test-rc
|
||||
namespace: test
|
||||
annotations:
|
||||
airshipit.org/initinfra: "workflow"
|
||||
labels:
|
||||
name: test-rc
|
||||
airshipit.org/initinfra: "workflow"
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: test-rc
|
||||
spec:
|
||||
containers:
|
||||
- name: test-rc
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
@ -15,10 +15,17 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
"sigs.k8s.io/cli-utils/pkg/manifestreader"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
)
|
||||
|
||||
// FactoryFromKubeConfigPath returns a factory with the
|
||||
@ -37,3 +44,55 @@ func Streams() genericclioptions.IOStreams {
|
||||
ErrOut: os.Stderr,
|
||||
}
|
||||
}
|
||||
|
||||
// ManifestReaderFactory factory function for manifestreader.ManifestReader
|
||||
type ManifestReaderFactory func(
|
||||
validate bool,
|
||||
bundle document.Bundle,
|
||||
factory cmdutil.Factory) manifestreader.ManifestReader
|
||||
|
||||
// DefaultManifestReaderFactory default factory function for manifestreader.ManifestReader
|
||||
var DefaultManifestReaderFactory ManifestReaderFactory = func(
|
||||
validate bool,
|
||||
bundle document.Bundle,
|
||||
factory cmdutil.Factory) manifestreader.ManifestReader {
|
||||
return NewManifestBundleReader(validate, bundle, factory)
|
||||
}
|
||||
|
||||
// NewManifestBundleReader returns impleemntation of manifestreader interface
|
||||
func NewManifestBundleReader(
|
||||
validate bool,
|
||||
bundle document.Bundle,
|
||||
factory cmdutil.Factory) *ManifestBundleReader {
|
||||
opts := manifestreader.ReaderOptions{
|
||||
Validate: validate,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Factory: factory,
|
||||
}
|
||||
buffer := bytes.NewBuffer([]byte{})
|
||||
return &ManifestBundleReader{
|
||||
Bundle: bundle,
|
||||
writer: buffer,
|
||||
StreamReader: &manifestreader.StreamManifestReader{
|
||||
ReaderName: "airship",
|
||||
Reader: buffer,
|
||||
ReaderOptions: opts,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ManifestBundleReader implements manifestreader interface that to transform bundle to slice
|
||||
// of *resource.Info objects using Read() method.
|
||||
type ManifestBundleReader struct {
|
||||
Bundle document.Bundle
|
||||
StreamReader *manifestreader.StreamManifestReader
|
||||
writer io.Writer
|
||||
}
|
||||
|
||||
func (mbr *ManifestBundleReader) Read() ([]*resource.Info, error) {
|
||||
err := mbr.Bundle.Write(mbr.writer)
|
||||
if err != nil {
|
||||
return []*resource.Info{}, err
|
||||
}
|
||||
return mbr.StreamReader.Read()
|
||||
}
|
||||
|
106
pkg/k8s/utils/utils_test.go
Normal file
106
pkg/k8s/utils/utils_test.go
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
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
|
||||
|
||||
https://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 utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/document"
|
||||
)
|
||||
|
||||
func TestDefaultManifestFactory(t *testing.T) {
|
||||
bundle, err := document.NewBundleByPath("testdata/source_bundle")
|
||||
require.NoError(t, err)
|
||||
reader := DefaultManifestReaderFactory(false, bundle, FactoryFromKubeConfigPath("testdata/kubeconfig.yaml"))
|
||||
require.NotNil(t, reader)
|
||||
}
|
||||
|
||||
func TestManifestBundleReader(t *testing.T) {
|
||||
bundle, err := document.NewBundleByPath("testdata/source_bundle")
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
errString string
|
||||
|
||||
reader io.Reader
|
||||
writer io.Writer
|
||||
}{
|
||||
{
|
||||
name: "Replication Controller Read Successfully",
|
||||
},
|
||||
{
|
||||
name: "Read error",
|
||||
errString: "Failed to read from bundle",
|
||||
reader: fakeReaderWriter{
|
||||
readErr: fmt.Errorf("Failed to read from bundle"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Write error",
|
||||
errString: "Failed to write bundle",
|
||||
writer: fakeReaderWriter{
|
||||
writeErr: fmt.Errorf("Failed to write bundle"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
reader := NewManifestBundleReader(false, bundle, FactoryFromKubeConfigPath("testdata/kubeconfig.yaml"))
|
||||
if tt.reader != nil {
|
||||
reader.StreamReader.Reader = tt.reader
|
||||
}
|
||||
if tt.writer != nil {
|
||||
reader.writer = tt.writer
|
||||
}
|
||||
infos, err := reader.Read()
|
||||
if tt.errString != "" {
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), tt.errString)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, infos, 1)
|
||||
obj := infos[0].Object
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
assert.Equal(t, gvk, schema.GroupVersionKind{
|
||||
Kind: "ReplicationController",
|
||||
Group: "",
|
||||
Version: "v1"})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeReaderWriter struct {
|
||||
readErr error
|
||||
writeErr error
|
||||
}
|
||||
|
||||
var _ io.Reader = fakeReaderWriter{}
|
||||
var _ io.Writer = fakeReaderWriter{}
|
||||
|
||||
func (f fakeReaderWriter) Read(p []byte) (n int, err error) {
|
||||
return 0, f.readErr
|
||||
}
|
||||
|
||||
func (f fakeReaderWriter) Write(p []byte) (n int, err error) {
|
||||
return 0, f.writeErr
|
||||
}
|
Loading…
Reference in New Issue
Block a user