Skip to content

Commit

Permalink
Merge pull request #1131 from huww98/metadata-profile
Browse files Browse the repository at this point in the history
metadata: split ack-cluster-profile to another provider
  • Loading branch information
k8s-ci-robot authored Aug 28, 2024
2 parents f0b77ad + 0634ba3 commit d8b52a6
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 72 deletions.
49 changes: 49 additions & 0 deletions pkg/cloud/metadata/ack_cluster_profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package metadata

import (
"context"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

type ProfileMetadata struct {
profile *v1.ConfigMap
}

var MetadataProfileDataKeys = map[MetadataKey]string{
ClusterID: "clusterid",
AccountID: "uid",
}

func NewProfileMetadata(client kubernetes.Interface) (*ProfileMetadata, error) {
profile, err := client.CoreV1().ConfigMaps("kube-system").Get(context.Background(), "ack-cluster-profile", metav1.GetOptions{})
if err != nil {
return nil, err
}
return &ProfileMetadata{profile: profile}, nil
}

func (m *ProfileMetadata) Get(key MetadataKey) (string, error) {
if key, ok := MetadataProfileDataKeys[key]; ok {
return m.profile.Data[key], nil
}
return "", ErrUnknownMetadataKey
}

type ProfileFetcher struct {
client kubernetes.Interface
}

func (f *ProfileFetcher) FetchFor(key MetadataKey) (MetadataProvider, error) {
_, ok := MetadataProfileDataKeys[key]
if !ok {
return nil, ErrUnknownMetadataKey
}
p, err := NewProfileMetadata(f.client)
if err != nil {
return nil, err
}
return newImmutableProvider(p, "ClusterProfile"), nil
}
43 changes: 43 additions & 0 deletions pkg/cloud/metadata/ack_cluster_profile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package metadata

import (
"testing"

"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fake "k8s.io/client-go/kubernetes/fake"
)

var testProfile = v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "ack-cluster-profile",
Namespace: "kube-system",
},
Data: map[string]string{
"clusterid": "c12345678",
"uid": "123456789",
},
}

func TestGetClusterProfile(t *testing.T) {
t.Parallel()

client := fake.NewSimpleClientset(&testProfile)
m, err := NewProfileMetadata(client)
assert.NoError(t, err)

expectedValues := map[MetadataKey]string{
AccountID: "123456789",
ClusterID: "c12345678",
}
for k, v := range expectedValues {
t.Log(k, v)
value, err := m.Get(k)
assert.NoError(t, err, k)
assert.Equal(t, v, value)
}
}

func TestGetClusterProfileNotFound(t *testing.T) {
}
42 changes: 13 additions & 29 deletions pkg/cloud/metadata/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ import (
"strings"

v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
)

type KubernetesMetadata struct {
node *v1.Node
profile *v1.ConfigMap
type KubernetesNodeMetadata struct {
node *v1.Node
}

var (
Expand Down Expand Up @@ -48,10 +46,6 @@ var MetadataLabels = map[MetadataKey][]string{
InstanceID: InstanceIdLabels,
}

var MetadataProfileDataKeys = map[MetadataKey]string{
ClusterID: "clusterid",
}

func init() {
envInstanceIdKey := os.Getenv("NODE_LABEL_ECS_ID_KEY")
if envInstanceIdKey != "" {
Expand All @@ -60,24 +54,15 @@ func init() {
}
}

func NewKubernetesMetadata(nodeName string, client kubernetes.Interface) (*KubernetesMetadata, error) {
node, err := client.CoreV1().Nodes().Get(context.Background(), nodeName, metav1.GetOptions{})
func NewKubernetesNodeMetadata(nodeName string, nodeClient corev1.NodeInterface) (*KubernetesNodeMetadata, error) {
node, err := nodeClient.Get(context.Background(), nodeName, metav1.GetOptions{})
if err != nil {
return nil, err
}
profile, err := client.CoreV1().ConfigMaps("kube-system").Get(context.Background(), "ack-cluster-profile", metav1.GetOptions{})
if err != nil && !apierrors.IsNotFound(err) {
return nil, err
}
return &KubernetesMetadata{node: node, profile: profile}, nil
return &KubernetesNodeMetadata{node: node}, nil
}

func (m *KubernetesMetadata) Get(key MetadataKey) (string, error) {

if key, ok := MetadataProfileDataKeys[key]; ok && m.profile != nil {
return m.profile.Data[key], nil
}

func (m *KubernetesNodeMetadata) Get(key MetadataKey) (string, error) {
labels := MetadataLabels[key]
for _, label := range labels {
if value, ok := m.node.Labels[label]; ok {
Expand All @@ -98,18 +83,17 @@ func (m *KubernetesMetadata) Get(key MetadataKey) (string, error) {
return "", ErrUnknownMetadataKey
}

type KubernetesMetadataFetcher struct {
client kubernetes.Interface
type KubernetesNodeMetadataFetcher struct {
client corev1.NodeInterface
nodeName string
}

func (f *KubernetesMetadataFetcher) FetchFor(key MetadataKey) (MetadataProvider, error) {
_, ok1 := MetadataLabels[key]
_, ok2 := MetadataProfileDataKeys[key]
if !ok1 && !ok2 {
func (f *KubernetesNodeMetadataFetcher) FetchFor(key MetadataKey) (MetadataProvider, error) {
_, ok := MetadataLabels[key]
if !ok {
return nil, ErrUnknownMetadataKey
}
p, err := NewKubernetesMetadata(f.nodeName, f.client)
p, err := NewKubernetesNodeMetadata(f.nodeName, f.client)
if err != nil {
return nil, err
}
Expand Down
33 changes: 3 additions & 30 deletions pkg/cloud/metadata/k8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,13 @@ var testNode = v1.Node{
},
}

var testProfile = v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "ack-cluster-profile",
Namespace: "kube-system",
},
}

func TestGetK8s(t *testing.T) {
t.Parallel()
cases := []struct {
name string
ProviderID string
Labels map[string]string
NotFound map[MetadataKey]bool
isACK bool
}{
{
name: "normal",
Expand All @@ -39,7 +31,6 @@ func TestGetK8s(t *testing.T) {
"topology.kubernetes.io/zone": "cn-hangzhou-a",
"node.kubernetes.io/instance-type": "ecs.g7.xlarge",
},
isACK: true,
},
{
name: "beta",
Expand All @@ -49,7 +40,6 @@ func TestGetK8s(t *testing.T) {
"failure-domain.beta.kubernetes.io/zone": "cn-hangzhou-a",
"beta.kubernetes.io/instance-type": "ecs.g7.xlarge",
},
isACK: true,
},
{
name: "sigma",
Expand All @@ -59,7 +49,6 @@ func TestGetK8s(t *testing.T) {
"sigma.ali/machine-model": "ecs.g7.xlarge",
"sigma.ali/ecs-instance-id": "i-2zec1slzwdzrwmvlr4w2",
},
isACK: true,
},
{
name: "alibabacloud",
Expand All @@ -72,17 +61,15 @@ func TestGetK8s(t *testing.T) {
NotFound: map[MetadataKey]bool{
InstanceType: true,
},
isACK: true,
},
{
name: "no label and non-ACK",
name: "no label",
ProviderID: "alicloud://cn-hangzhou.i-2zec1slzwdzrwmvlr4w2",
Labels: map[string]string{},
NotFound: map[MetadataKey]bool{
ZoneID: true,
InstanceType: true,
},
isACK: false,
},
}
expectedValues := map[MetadataKey]string{
Expand All @@ -99,14 +86,8 @@ func TestGetK8s(t *testing.T) {
node.Spec.ProviderID = c.ProviderID
node.Labels = c.Labels

client := fake.NewSimpleClientset(node)
if c.isACK {
profile := testProfile.DeepCopy()
profile.Data = map[string]string{}
profile.Data["clusterid"] = "c12345678"
client = fake.NewSimpleClientset(node, profile)
}
m, err := NewKubernetesMetadata(node.Name, client)
client := fake.NewSimpleClientset(node).CoreV1().Nodes()
m, err := NewKubernetesNodeMetadata(node.Name, client)
assert.NoError(t, err)

for k, v := range expectedValues {
Expand All @@ -119,14 +100,6 @@ func TestGetK8s(t *testing.T) {
assert.Equal(t, v, value)
}
}

value, err := m.Get(ClusterID)
if c.isACK {
assert.NoError(t, err)
assert.Equal(t, "c12345678", value)
} else {
assert.Equal(t, ErrUnknownMetadataKey, err)
}
})
}
}
15 changes: 10 additions & 5 deletions pkg/cloud/metadata/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,18 @@ func (m *Metadata) EnableEcs(httpRT http.RoundTripper) {
func (m *Metadata) EnableKubernetes(client kubernetes.Interface) {
nodeName := os.Getenv(KUBE_NODE_NAME_ENV)
if nodeName == "" {
logrus.Warnf("%s environment variable is not set, skipping Kubernetes metadata", KUBE_NODE_NAME_ENV)
return
logrus.Warnf("%s environment variable is not set, skipping Kubernetes Node metadata", KUBE_NODE_NAME_ENV)
} else {
m.providers = append(m.providers, &lazyInitProvider{
fetcher: &KubernetesNodeMetadataFetcher{
client: client.CoreV1().Nodes(),
nodeName: nodeName,
},
})
}
m.providers = append(m.providers, &lazyInitProvider{
fetcher: &KubernetesMetadataFetcher{
client: client,
nodeName: nodeName,
fetcher: &ProfileFetcher{
client: client,
},
})
}
Expand Down
20 changes: 12 additions & 8 deletions pkg/cloud/metadata/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,33 @@ func TestCreateK8s(t *testing.T) {
node.Labels = map[string]string{
"topology.kubernetes.io/region": "cn-beijing",
}
profile := testProfile.DeepCopy()
profile.Data = map[string]string{}
profile.Data["clusterid"] = "c12345678"

client := fake.NewSimpleClientset(node, profile)
client := fake.NewSimpleClientset(node, &testProfile)
t.Run("no node name", func(t *testing.T) {
m.EnableKubernetes(client)
_, err := m.Get(RegionID)
assert.Equal(t, ErrUnknownMetadataKey, err)
assert.Equal(t, "c12345678", MustGet(m, ClusterID))
})

t.Run("ok", func(t *testing.T) {
t.Setenv(KUBE_NODE_NAME_ENV, testNode.Name)
m.EnableKubernetes(client)
assert.Equal(t, "cn-beijing", MustGet(m, RegionID))
})

t.Run("profile", func(t *testing.T) {
m.EnableKubernetes(client)
assert.Equal(t, "c12345678", MustGet(m, ClusterID))
})
}

func TestK8sNoProfile(t *testing.T) {
m := NewMetadata()

client := fake.NewSimpleClientset()
m.EnableKubernetes(client)
_, err := m.Get(ClusterID)
assert.ErrorContains(t, err, "ack-cluster-profile")
assert.ErrorContains(t, err, "not found")
}

func TestGetFromEnv(t *testing.T) {
t.Setenv("REGION_ID", "cn-hangzhou")
m := NewMetadata()
Expand Down

0 comments on commit d8b52a6

Please sign in to comment.