Skip to content

Commit d829b22

Browse files
committed
Support nic lingjun node type
1 parent c1e7f0d commit d829b22

3 files changed

Lines changed: 319 additions & 3 deletions

File tree

pkg/cloud/metadata/lingjun.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package metadata
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
)
7+
8+
var LingjunConfigFile = "/host/etc/eflo_config/lingjun_config"
9+
10+
type LingjunMetaData struct {
11+
RegionId string `json:"RegionId"`
12+
ZoneId string `json:"ZoneId"`
13+
NodeId string `json:"NodeId"`
14+
InstanceType string `json:"InstanceType"`
15+
EniMac string `json:"EniMac"`
16+
AckNicName string `json:"AckNicName"`
17+
NimitzNetworkMode string `json:"NimitzNetworkMode"`
18+
NimitzInterface []string `json:"NimitzInterface"`
19+
}
20+
21+
var LingjunConfig = map[MetadataKey]string{
22+
RegionID: "RegionId",
23+
ZoneID: "ZoneId",
24+
InstanceID: "NodeId",
25+
InstanceType: "InstanceType",
26+
}
27+
28+
func NewLingJunMetadata() (*LingjunMetaData, error) {
29+
lm := LingjunMetaData{}
30+
data, err := os.ReadFile(LingjunConfigFile)
31+
if err != nil {
32+
return nil, err
33+
}
34+
err = json.Unmarshal(data, &lm)
35+
if err != nil {
36+
return nil, err
37+
}
38+
return &lm, nil
39+
}
40+
41+
func (m *LingjunMetaData) Get(key MetadataKey) (string, error) {
42+
43+
if v, ok := LingjunConfig[key]; ok {
44+
switch v {
45+
case "RegionId":
46+
return m.RegionId, nil
47+
case "ZoneId":
48+
return m.ZoneId, nil
49+
case "NodeId":
50+
return m.NodeId, nil
51+
case "InstanceType":
52+
return m.InstanceType, nil
53+
}
54+
}
55+
return "", ErrUnknownMetadataKey
56+
}
57+
58+
type LingJunFetcher struct {
59+
}
60+
61+
func (f *LingJunFetcher) FetchFor(key MetadataKey) (MetadataProvider, error) {
62+
switch key {
63+
case RegionID, ZoneID, InstanceID, InstanceType:
64+
default:
65+
return nil, ErrUnknownMetadataKey
66+
}
67+
68+
lingjun, err := NewLingJunMetadata()
69+
if err != nil {
70+
// if errors.Is(err, os.ErrNotExist) {
71+
// klog.Warningf("Hint: LingJun metadata is only available when running on LingJun instance type.")
72+
// }
73+
return nil, err
74+
}
75+
return newImmutableProvider(lingjun, "LingJun"), nil
76+
}

pkg/cloud/metadata/lingjun_test.go

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
package metadata
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestNewLingJunMetadata(t *testing.T) {
13+
// Create a temporary directory for our test file
14+
tempDir := t.TempDir()
15+
originalConfigFile := LingjunConfigFile
16+
LingjunConfigFile = filepath.Join(tempDir, "lingjun_config")
17+
defer func() {
18+
LingjunConfigFile = originalConfigFile
19+
}()
20+
21+
t.Run("success case", func(t *testing.T) {
22+
// Prepare test data
23+
testData := LingjunMetaData{
24+
RegionId: "cn-hangzhou",
25+
ZoneId: "cn-hangzhou-a",
26+
NodeId: "i-1234567890abcdef0",
27+
InstanceType: "ecs.g6.large",
28+
EniMac: "00:11:22:33:44:55",
29+
AckNicName: "eth1",
30+
NimitzNetworkMode: "VPC",
31+
NimitzInterface: []string{"eth0", "eth1"},
32+
}
33+
34+
data, err := json.Marshal(testData)
35+
assert.NoError(t, err)
36+
37+
err = os.WriteFile(LingjunConfigFile, data, 0644)
38+
assert.NoError(t, err)
39+
40+
// Test the function
41+
result, err := NewLingJunMetadata()
42+
assert.NoError(t, err)
43+
assert.NotNil(t, result)
44+
assert.Equal(t, testData.RegionId, result.RegionId)
45+
assert.Equal(t, testData.ZoneId, result.ZoneId)
46+
assert.Equal(t, testData.NodeId, result.NodeId)
47+
assert.Equal(t, testData.InstanceType, result.InstanceType)
48+
assert.Equal(t, testData.EniMac, result.EniMac)
49+
assert.Equal(t, testData.AckNicName, result.AckNicName)
50+
assert.Equal(t, testData.NimitzNetworkMode, result.NimitzNetworkMode)
51+
assert.Equal(t, testData.NimitzInterface, result.NimitzInterface)
52+
})
53+
54+
t.Run("file not exist", func(t *testing.T) {
55+
nonExistFile := filepath.Join(tempDir, "non_exist")
56+
LingjunConfigFile = nonExistFile
57+
58+
result, err := NewLingJunMetadata()
59+
assert.Error(t, err)
60+
assert.Nil(t, result)
61+
assert.True(t, os.IsNotExist(err))
62+
})
63+
64+
t.Run("invalid json", func(t *testing.T) {
65+
invalidJsonFile := filepath.Join(tempDir, "invalid_json")
66+
LingjunConfigFile = invalidJsonFile
67+
68+
err := os.WriteFile(invalidJsonFile, []byte("{ invalid json }"), 0644)
69+
assert.NoError(t, err)
70+
71+
result, err := NewLingJunMetadata()
72+
assert.Error(t, err)
73+
assert.Nil(t, result)
74+
})
75+
}
76+
77+
func TestLingjunMetaData_Get(t *testing.T) {
78+
metaData := &LingjunMetaData{
79+
RegionId: "cn-hangzhou",
80+
ZoneId: "cn-hangzhou-a",
81+
NodeId: "i-1234567890abcdef0",
82+
InstanceType: "ecs.g6.large",
83+
EniMac: "00:11:22:33:44:55",
84+
AckNicName: "eth1",
85+
NimitzNetworkMode: "VPC",
86+
NimitzInterface: []string{"eth0", "eth1"},
87+
}
88+
89+
tests := []struct {
90+
name string
91+
key MetadataKey
92+
expectedVal string
93+
expectErr bool
94+
}{
95+
{
96+
name: "get region id",
97+
key: RegionID,
98+
expectedVal: "cn-hangzhou",
99+
expectErr: false,
100+
},
101+
{
102+
name: "get zone id",
103+
key: ZoneID,
104+
expectedVal: "cn-hangzhou-a",
105+
expectErr: false,
106+
},
107+
{
108+
name: "get instance id",
109+
key: InstanceID,
110+
expectedVal: "i-1234567890abcdef0",
111+
expectErr: false,
112+
},
113+
{
114+
name: "get instance type",
115+
key: InstanceType,
116+
expectedVal: "ecs.g6.large",
117+
expectErr: false,
118+
},
119+
{
120+
name: "get unknown key",
121+
key: AccountID,
122+
expectedVal: "",
123+
expectErr: true,
124+
},
125+
}
126+
127+
for _, tt := range tests {
128+
t.Run(tt.name, func(t *testing.T) {
129+
value, err := metaData.Get(tt.key)
130+
if tt.expectErr {
131+
assert.Error(t, err)
132+
assert.Equal(t, "", value)
133+
assert.Equal(t, ErrUnknownMetadataKey, err)
134+
} else {
135+
assert.NoError(t, err)
136+
assert.Equal(t, tt.expectedVal, value)
137+
}
138+
})
139+
}
140+
}
141+
142+
func TestLingJunFetcher_FetchFor(t *testing.T) {
143+
tempDir := t.TempDir()
144+
originalConfigFile := LingjunConfigFile
145+
LingjunConfigFile = filepath.Join(tempDir, "lingjun_config")
146+
defer func() {
147+
LingjunConfigFile = originalConfigFile
148+
}()
149+
150+
// Prepare test data
151+
testData := LingjunMetaData{
152+
RegionId: "cn-hangzhou",
153+
ZoneId: "cn-hangzhou-a",
154+
NodeId: "i-1234567890abcdef0",
155+
InstanceType: "ecs.g6.large",
156+
EniMac: "00:11:22:33:44:55",
157+
AckNicName: "eth1",
158+
NimitzNetworkMode: "VPC",
159+
NimitzInterface: []string{"eth0", "eth1"},
160+
}
161+
162+
data, err := json.Marshal(testData)
163+
assert.NoError(t, err)
164+
165+
err = os.WriteFile(LingjunConfigFile, data, 0644)
166+
assert.NoError(t, err)
167+
168+
fetcher := &LingJunFetcher{}
169+
170+
tests := []struct {
171+
name string
172+
key MetadataKey
173+
expectErr bool
174+
}{
175+
{
176+
name: "fetch region id",
177+
key: RegionID,
178+
expectErr: false,
179+
},
180+
{
181+
name: "fetch zone id",
182+
key: ZoneID,
183+
expectErr: false,
184+
},
185+
{
186+
name: "fetch instance id",
187+
key: InstanceID,
188+
expectErr: false,
189+
},
190+
{
191+
name: "fetch instance type",
192+
key: InstanceType,
193+
expectErr: false,
194+
},
195+
{
196+
name: "fetch unsupported key",
197+
key: AccountID,
198+
expectErr: true,
199+
},
200+
}
201+
202+
for _, tt := range tests {
203+
t.Run(tt.name, func(t *testing.T) {
204+
provider, err := fetcher.FetchFor(tt.key)
205+
if tt.expectErr {
206+
assert.Error(t, err)
207+
assert.Nil(t, provider)
208+
} else {
209+
assert.NoError(t, err)
210+
assert.NotNil(t, provider)
211+
212+
// Test that the provider works correctly
213+
value, err := provider.Get(tt.key)
214+
assert.NoError(t, err)
215+
assert.NotEmpty(t, value)
216+
217+
// Verify it's actually the right provider
218+
if immProvider, ok := provider.(*immutableProvider); ok {
219+
assert.Equal(t, "LingJun", immProvider.name)
220+
}
221+
}
222+
})
223+
}
224+
}
225+
226+
func TestLingJunFetcher_FetchFor_Error(t *testing.T) {
227+
tempDir := t.TempDir()
228+
originalConfigFile := LingjunConfigFile
229+
LingjunConfigFile = filepath.Join(tempDir, "nonexistent")
230+
defer func() {
231+
LingjunConfigFile = originalConfigFile
232+
}()
233+
234+
fetcher := &LingJunFetcher{}
235+
236+
provider, err := fetcher.FetchFor(RegionID)
237+
assert.Error(t, err)
238+
assert.Nil(t, provider)
239+
}

pkg/cloud/metadata/metadata.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,10 @@ func NewMetadata() *Metadata {
139139
return &Metadata{
140140
providers: []MetadataProvider{
141141
newImmutableProvider(&ENVMetadata{}, "env"),
142-
},
143-
}
142+
&lazyInitProvider{
143+
fetcher: &LingJunFetcher{},
144+
},
145+
}}
144146
}
145147

146148
func (m *Metadata) EnableEcs(httpRT http.RoundTripper) {
@@ -151,7 +153,6 @@ func (m *Metadata) EnableEcs(httpRT http.RoundTripper) {
151153
m.providers = append(m.providers, &lazyInitProvider{
152154
fetcher: &EcsFetcher{httpRT: httpRT},
153155
}, NewEcsDynamic(httpRT))
154-
155156
}
156157

157158
func (m *Metadata) EnableKubernetes(client kubernetes.Interface) {

0 commit comments

Comments
 (0)