-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a helper func for setting agent install namespace from addon depl…
…oyment config Signed-off-by: zhujian <jiazhu@redhat.com>
- Loading branch information
Showing
45 changed files
with
1,436 additions
and
2,191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package utils | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||
"k8s.io/klog/v2" | ||
addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" | ||
) | ||
|
||
func AgentInstallNamespaceFromDeploymentConfig( | ||
adcgetter func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error), | ||
) func(*addonapiv1alpha1.ManagedClusterAddOn) string { | ||
return func(addon *addonapiv1alpha1.ManagedClusterAddOn) string { | ||
if addon == nil { | ||
utilruntime.HandleError(fmt.Errorf("failed to get addon template, addon is nil")) | ||
return "" | ||
} | ||
|
||
config, err := GetDesiredAddOnDeploymentConfig(addon, adcgetter) | ||
if err != nil { | ||
utilruntime.HandleError(fmt.Errorf("failed to get addon %s template: %v", addon.Name, err)) | ||
return "" | ||
} | ||
if config == nil { | ||
return "" | ||
} | ||
|
||
return config.Spec.AgentInstallNamespace | ||
} | ||
} | ||
|
||
// GetDesiredAddOnDeployment returns the desired template of the addon | ||
func GetDesiredAddOnDeploymentConfig( | ||
addon *addonapiv1alpha1.ManagedClusterAddOn, | ||
adcgetter func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error), | ||
) (*addonapiv1alpha1.AddOnDeploymentConfig, error) { | ||
|
||
ok, configRef := GetAddonConfigRef(addon.Status.ConfigReferences, | ||
AddOnDeploymentConfigGVR.Group, AddOnDeploymentConfigGVR.Resource) | ||
if !ok { | ||
klog.InfoS("Addon deployment config in status is empty", "addonName", addon.Name) | ||
return nil, nil | ||
} | ||
|
||
desiredConfig := configRef.DesiredConfig | ||
if desiredConfig == nil || len(desiredConfig.SpecHash) == 0 { | ||
klog.InfoS("Addon deployment config spec hash is empty", "addonName", addon.Name) | ||
return nil, fmt.Errorf("addon %s deployment config desired spec hash is empty", addon.Name) | ||
} | ||
|
||
adc, err := adcgetter(context.TODO(), desiredConfig.Namespace, desiredConfig.Name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
specHash, err := GetAddOnDeploymentConfigSpecHash(adc) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if specHash != desiredConfig.SpecHash { | ||
return nil, fmt.Errorf("addon %s deployment config spec hash %s is not equal to desired spec hash %s", | ||
addon.Name, specHash, desiredConfig.SpecHash) | ||
} | ||
return adc.DeepCopy(), nil | ||
} | ||
|
||
// GetAddOnDeploymentConfigSpecHash returns the sha256 hash of the spec field of the addon deployment config | ||
func GetAddOnDeploymentConfigSpecHash(config *addonapiv1alpha1.AddOnDeploymentConfig) (string, error) { | ||
if config == nil { | ||
return "", fmt.Errorf("addon deployment config is nil") | ||
} | ||
uadc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(config) | ||
if err != nil { | ||
return "", err | ||
} | ||
return GetSpecHash(&unstructured.Unstructured{ | ||
Object: uadc, | ||
}) | ||
} | ||
|
||
// GetAddOnTemplateSpecHash returns the sha256 hash of the spec field of the addon template | ||
func GetAddOnTemplateSpecHash(template *addonapiv1alpha1.AddOnTemplate) (string, error) { | ||
if template == nil { | ||
return "", fmt.Errorf("addon template is nil") | ||
} | ||
uat, err := runtime.DefaultUnstructuredConverter.ToUnstructured(template) | ||
if err != nil { | ||
return "", err | ||
} | ||
return GetSpecHash(&unstructured.Unstructured{ | ||
Object: uat, | ||
}) | ||
} | ||
|
||
// GetAddonConfigRef returns the first addon config ref for the given config type | ||
func GetAddonConfigRef( | ||
configReferences []addonapiv1alpha1.ConfigReference, | ||
group, resource string) (bool, addonapiv1alpha1.ConfigReference) { | ||
|
||
for _, config := range configReferences { | ||
if config.Group == group && config.Resource == resource { | ||
return true, config | ||
} | ||
} | ||
return false, addonapiv1alpha1.ConfigReference{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
package utils | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" | ||
) | ||
|
||
func TestAgentInstallNamespaceFromDeploymentConfig(t *testing.T) { | ||
|
||
cases := []struct { | ||
name string | ||
getter func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error) | ||
mca *addonapiv1alpha1.ManagedClusterAddOn | ||
expected string | ||
}{ | ||
{ | ||
name: "addon is nil", | ||
getter: func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error) { | ||
return &addonapiv1alpha1.AddOnDeploymentConfig{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
}, | ||
Spec: addonapiv1alpha1.AddOnDeploymentConfigSpec{}, | ||
}, nil | ||
}, | ||
mca: nil, | ||
expected: "", | ||
}, | ||
{ | ||
name: "addon no deployment config reference", | ||
getter: func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error) { | ||
return &addonapiv1alpha1.AddOnDeploymentConfig{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
}, | ||
Spec: addonapiv1alpha1.AddOnDeploymentConfigSpec{}, | ||
}, nil | ||
}, | ||
mca: &addonapiv1alpha1.ManagedClusterAddOn{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
Namespace: "cluster1", | ||
}, | ||
Status: addonapiv1alpha1.ManagedClusterAddOnStatus{ | ||
ConfigReferences: []addonapiv1alpha1.ConfigReference{}, | ||
}, | ||
}, | ||
expected: "", | ||
}, | ||
{ | ||
name: "addon deployment config reference spec hash empty", | ||
getter: func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error) { | ||
return &addonapiv1alpha1.AddOnDeploymentConfig{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
}, | ||
Spec: addonapiv1alpha1.AddOnDeploymentConfigSpec{}, | ||
}, nil | ||
}, | ||
mca: &addonapiv1alpha1.ManagedClusterAddOn{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
Namespace: "cluster1", | ||
}, | ||
Status: addonapiv1alpha1.ManagedClusterAddOnStatus{ | ||
ConfigReferences: []addonapiv1alpha1.ConfigReference{ | ||
{ | ||
ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ | ||
Group: "addon.open-cluster-management.io", | ||
Resource: "addondeploymentconfigs", | ||
}, | ||
ConfigReferent: addonapiv1alpha1.ConfigReferent{ | ||
Name: "test1", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
expected: "", | ||
}, | ||
{ | ||
name: "addon deployment config reference spec hash not match", | ||
getter: func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error) { | ||
return &addonapiv1alpha1.AddOnDeploymentConfig{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
}, | ||
Spec: addonapiv1alpha1.AddOnDeploymentConfigSpec{ | ||
AgentInstallNamespace: "testns", | ||
}, | ||
}, nil | ||
}, | ||
mca: &addonapiv1alpha1.ManagedClusterAddOn{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
Namespace: "cluster1", | ||
}, | ||
Status: addonapiv1alpha1.ManagedClusterAddOnStatus{ | ||
ConfigReferences: []addonapiv1alpha1.ConfigReference{ | ||
{ | ||
ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ | ||
Group: "addon.open-cluster-management.io", | ||
Resource: "addondeploymentconfigs", | ||
}, | ||
ConfigReferent: addonapiv1alpha1.ConfigReferent{ | ||
Name: "test1", | ||
}, | ||
DesiredConfig: &addonapiv1alpha1.ConfigSpecHash{ | ||
SpecHash: "wronghash", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
expected: "", | ||
}, | ||
{ | ||
name: "addon deployment config reference spec hash match", | ||
getter: func(ctx context.Context, namespace, name string) (*addonapiv1alpha1.AddOnDeploymentConfig, error) { | ||
return &addonapiv1alpha1.AddOnDeploymentConfig{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
}, | ||
Spec: addonapiv1alpha1.AddOnDeploymentConfigSpec{ | ||
AgentInstallNamespace: "testns", | ||
}, | ||
}, nil | ||
}, | ||
mca: &addonapiv1alpha1.ManagedClusterAddOn{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
Namespace: "cluster1", | ||
}, | ||
Status: addonapiv1alpha1.ManagedClusterAddOnStatus{ | ||
ConfigReferences: []addonapiv1alpha1.ConfigReference{ | ||
{ | ||
ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ | ||
Group: "addon.open-cluster-management.io", | ||
Resource: "addondeploymentconfigs", | ||
}, | ||
ConfigReferent: addonapiv1alpha1.ConfigReferent{ | ||
Name: "test1", | ||
}, | ||
DesiredConfig: &addonapiv1alpha1.ConfigSpecHash{ | ||
SpecHash: "f97b3f6af1f786ec6f3273e2d6fc8717e45cb7bc9797ba7533663a7de84a5538", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
expected: "testns", | ||
}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.name, func(t *testing.T) { | ||
nsFunc := AgentInstallNamespaceFromDeploymentConfig(c.getter) | ||
ns := nsFunc(c.mca) | ||
assert.Equal(t, c.expected, ns, "should be equal") | ||
}) | ||
} | ||
} | ||
|
||
func TestGetAddOnTemplateSpecHash(t *testing.T) { | ||
cases := []struct { | ||
name string | ||
at *addonapiv1alpha1.AddOnTemplate | ||
expected string | ||
expectedErr string | ||
}{ | ||
{ | ||
name: "addon template is nil", | ||
at: nil, | ||
expected: "", | ||
expectedErr: "addon template is nil", | ||
}, | ||
{ | ||
name: "addon template spec is nil", | ||
at: &addonapiv1alpha1.AddOnTemplate{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
}, | ||
Spec: addonapiv1alpha1.AddOnTemplateSpec{}, | ||
}, | ||
expected: "aa3e489402ac2e99c4aef0ddc8cc2fdf1d3b6c34c7b8d040dc3fae5db60478cb", | ||
}, | ||
{ | ||
name: "addon template spec is not nil", | ||
at: &addonapiv1alpha1.AddOnTemplate{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "test1", | ||
}, | ||
Spec: addonapiv1alpha1.AddOnTemplateSpec{ | ||
AddonName: "test1", | ||
}, | ||
}, | ||
expected: "00730aa8aa1826c9a3cfd8d6858b45e1e16bcdade5cc57070ea8089c6764285e", | ||
}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.name, func(t *testing.T) { | ||
hash, err := GetAddOnTemplateSpecHash(c.at) | ||
if c.expectedErr != "" { | ||
assert.Equal(t, c.expectedErr, err.Error(), "should be equal") | ||
} else { | ||
assert.Nil(t, err, "should be nil") | ||
} | ||
assert.Equal(t, c.expected, hash, "should be equal") | ||
}) | ||
} | ||
} |
Oops, something went wrong.