Add new selector by ObjectReference
This selector will allow us to improve internal logic in places where we create selectors by ObjectReference objects and reuse the code. Change-Id: I4e4808bfdffc4446e9df255e2ed0b7b8f47d135c Signed-off-by: Ruslan Aliev <raliev@mirantis.com>
This commit is contained in:
parent
a377007ad0
commit
bd287ce369
@ -18,9 +18,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||||
)
|
)
|
||||||
@ -104,6 +104,15 @@ func (s Selector) ByObject(obj runtime.Object, scheme *runtime.Scheme) (Selector
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByObjectReference select by ObjectReference
|
||||||
|
func (s Selector) ByObjectReference(objRef *corev1.ObjectReference) Selector {
|
||||||
|
refGVK := objRef.GroupVersionKind()
|
||||||
|
return NewSelector().
|
||||||
|
ByGvk(refGVK.Group, refGVK.Version, refGVK.Kind).
|
||||||
|
ByName(objRef.Name).
|
||||||
|
ByNamespace(objRef.Namespace)
|
||||||
|
}
|
||||||
|
|
||||||
// String is a convenience function which dumps all relevant information about a Selector in the following format:
|
// String is a convenience function which dumps all relevant information about a Selector in the following format:
|
||||||
// [Key1=Value1, Key2=Value2, ...]
|
// [Key1=Value1, Key2=Value2, ...]
|
||||||
func (s Selector) String() string {
|
func (s Selector) String() string {
|
||||||
|
@ -208,3 +208,41 @@ func TestSelectorToObject(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSelectorByObjRef(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
objRef *k8sv1.ObjectReference
|
||||||
|
expectedSel document.Selector
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Selector with GVK, name and namespace",
|
||||||
|
objRef: &k8sv1.ObjectReference{
|
||||||
|
Kind: "TestKind",
|
||||||
|
Name: "TestName",
|
||||||
|
APIVersion: "api.version/v1",
|
||||||
|
Namespace: "TestNamespace",
|
||||||
|
},
|
||||||
|
expectedSel: document.Selector{
|
||||||
|
Selector: types.Selector{
|
||||||
|
ResId: resid.ResId{
|
||||||
|
Gvk: resid.Gvk{
|
||||||
|
Group: "api.version",
|
||||||
|
Version: "v1",
|
||||||
|
Kind: "TestKind",
|
||||||
|
},
|
||||||
|
Name: "TestName",
|
||||||
|
Namespace: "TestNamespace",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
tt := test
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
actualSel := document.NewSelector().ByObjectReference(tt.objRef)
|
||||||
|
assert.Equal(t, tt.expectedSel, actualSel)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -63,24 +63,10 @@ type phase struct {
|
|||||||
processor events.EventProcessor
|
processor events.EventProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *phase) defaultBundleFactory() document.BundleFactoryFunc {
|
|
||||||
return document.BundleFactoryFromDocRoot(p.DocumentRoot)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *phase) defaultDocFactory() document.DocFactoryFunc {
|
|
||||||
return func() (document.Document, error) {
|
|
||||||
return p.helper.ExecutorDoc(ifc.ID{Name: p.apiObj.Name, Namespace: p.apiObj.Namespace})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Executor returns executor interface associated with the phase
|
// Executor returns executor interface associated with the phase
|
||||||
func (p *phase) Executor() (ifc.Executor, error) {
|
func (p *phase) Executor() (ifc.Executor, error) {
|
||||||
return p.executor(p.defaultDocFactory(), p.defaultBundleFactory())
|
executorDoc, err := p.helper.PhaseConfigBundle().SelectOne(
|
||||||
}
|
document.NewSelector().ByObjectReference(p.apiObj.Config.ExecutorRef))
|
||||||
|
|
||||||
func (p *phase) executor(docFactory document.DocFactoryFunc,
|
|
||||||
bundleFactory document.BundleFactoryFunc) (ifc.Executor, error) {
|
|
||||||
executorDoc, err := docFactory()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -112,7 +98,7 @@ func (p *phase) executor(docFactory document.DocFactoryFunc,
|
|||||||
return executorFactory(
|
return executorFactory(
|
||||||
ifc.ExecutorConfig{
|
ifc.ExecutorConfig{
|
||||||
ClusterMap: cMap,
|
ClusterMap: cMap,
|
||||||
BundleFactory: bundleFactory,
|
BundleFactory: document.BundleFactoryFromDocRoot(p.DocumentRoot),
|
||||||
PhaseName: p.apiObj.Name,
|
PhaseName: p.apiObj.Name,
|
||||||
KubeConfig: kubeconf,
|
KubeConfig: kubeconf,
|
||||||
ExecutorDocument: executorDoc,
|
ExecutorDocument: executorDoc,
|
||||||
|
@ -233,13 +233,6 @@ func TestPhaseValidate(t *testing.T) {
|
|||||||
registryFunc: fakeRegistry,
|
registryFunc: fakeRegistry,
|
||||||
errContains: "executor identified by 'airshipit.org/v1alpha1, Kind=SomeExecutor' is not found",
|
errContains: "executor identified by 'airshipit.org/v1alpha1, Kind=SomeExecutor' is not found",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Error no executor",
|
|
||||||
configFunc: testConfig,
|
|
||||||
phaseID: ifc.ID{Name: "no_executor_phase"},
|
|
||||||
registryFunc: fakeRegistry,
|
|
||||||
errContains: "Phase name 'no_executor_phase', namespace '' must have executorRef field defined in config",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Error executor validate",
|
name: "Error executor validate",
|
||||||
configFunc: testConfig,
|
configFunc: testConfig,
|
||||||
|
@ -182,12 +182,7 @@ func (c *ContainerExecutor) Render(w io.Writer, o ifc.RenderOptions) error {
|
|||||||
func (c *ContainerExecutor) setConfig() error {
|
func (c *ContainerExecutor) setConfig() error {
|
||||||
if c.Container.ConfigRef != nil {
|
if c.Container.ConfigRef != nil {
|
||||||
log.Debugf("Config reference is specified, looking for the object in config ref: '%v'", c.Container.ConfigRef)
|
log.Debugf("Config reference is specified, looking for the object in config ref: '%v'", c.Container.ConfigRef)
|
||||||
gvk := c.Container.ConfigRef.GroupVersionKind()
|
doc, err := c.Options.PhaseConfigBundle.SelectOne(document.NewSelector().ByObjectReference(c.Container.ConfigRef))
|
||||||
selector := document.NewSelector().
|
|
||||||
ByName(c.Container.ConfigRef.Name).
|
|
||||||
ByNamespace(c.Container.ConfigRef.Namespace).
|
|
||||||
ByGvk(gvk.Group, gvk.Version, gvk.Kind)
|
|
||||||
doc, err := c.Options.PhaseConfigBundle.SelectOne(selector)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,13 @@ func (helper *Helper) Phase(phaseID ifc.ID) (*v1alpha1.Phase, error) {
|
|||||||
if err = doc.ToAPIObject(phase, v1alpha1.Scheme); err != nil {
|
if err = doc.ToAPIObject(phase, v1alpha1.Scheme); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// Phase must contain an executor
|
||||||
|
if phase.Config.ExecutorRef == nil {
|
||||||
|
return nil, errors.ErrExecutorRefNotDefined{
|
||||||
|
PhaseName: phase.Name,
|
||||||
|
PhaseNamespace: phase.Namespace,
|
||||||
|
}
|
||||||
|
}
|
||||||
return phase, nil
|
return phase, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,19 +278,9 @@ func (helper *Helper) ExecutorDoc(phaseID ifc.ID) (document.Document, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
phaseConfig := phaseObj.Config
|
|
||||||
if phaseConfig.ExecutorRef == nil {
|
|
||||||
return nil, errors.ErrExecutorRefNotDefined{PhaseName: phaseID.Name, PhaseNamespace: phaseID.Namespace}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Searching executor configuration document referenced in
|
// Searching executor configuration document referenced in
|
||||||
// phase configuration
|
// phase configuration
|
||||||
refGVK := phaseConfig.ExecutorRef.GroupVersionKind()
|
return helper.phaseConfigBundle.SelectOne(document.NewSelector().ByObjectReference(phaseObj.Config.ExecutorRef))
|
||||||
selector := document.NewSelector().
|
|
||||||
ByGvk(refGVK.Group, refGVK.Version, refGVK.Kind).
|
|
||||||
ByName(phaseConfig.ExecutorRef.Name).
|
|
||||||
ByNamespace(phaseConfig.ExecutorRef.Namespace)
|
|
||||||
return helper.phaseConfigBundle.SelectOne(selector)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TargetPath returns manifest root
|
// TargetPath returns manifest root
|
||||||
|
@ -75,6 +75,12 @@ func TestHelperPhase(t *testing.T) {
|
|||||||
phaseID: ifc.ID{Name: "some_name"},
|
phaseID: ifc.ID{Name: "some_name"},
|
||||||
errContains: "found no documents",
|
errContains: "found no documents",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Error no executor",
|
||||||
|
config: testConfig,
|
||||||
|
phaseID: ifc.ID{Name: "no_executor_phase"},
|
||||||
|
errContains: "Phase name 'no_executor_phase', namespace '' must have executorRef field defined in config",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Error bundle path doesn't exist",
|
name: "Error bundle path doesn't exist",
|
||||||
config: func(t *testing.T) *config.Config {
|
config: func(t *testing.T) *config.Config {
|
||||||
@ -95,6 +101,7 @@ func TestHelperPhase(t *testing.T) {
|
|||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
require.NotNil(t, helper)
|
require.NotNil(t, helper)
|
||||||
actualPhase, actualErr := helper.Phase(tt.phaseID)
|
actualPhase, actualErr := helper.Phase(tt.phaseID)
|
||||||
if tt.errContains != "" {
|
if tt.errContains != "" {
|
||||||
|
@ -3,4 +3,8 @@ kind: Phase
|
|||||||
metadata:
|
metadata:
|
||||||
name: sample
|
name: sample
|
||||||
config:
|
config:
|
||||||
|
executorRef:
|
||||||
|
apiVersion: airshipit.org/v1alpha1
|
||||||
|
kind: SomeExecutor
|
||||||
|
name: executor-name
|
||||||
documentEntryPoint: entrypoint
|
documentEntryPoint: entrypoint
|
Loading…
Reference in New Issue
Block a user