@@ -44,6 +44,18 @@ const (
44
44
configDriveUserdataPath = "/openstack/latest/user_data"
45
45
)
46
46
47
+ var (
48
+ metadataServiceUrlIPv4 = url.URL {
49
+ Scheme : "http" ,
50
+ Host : "169.254.169.254" ,
51
+ Path : "openstack/latest/user_data" ,
52
+ }
53
+ metadataServiceUrlIPv6 = url.URL {
54
+ Scheme : "http" ,
55
+ Path : "openstack/latest/user_data" ,
56
+ }
57
+ )
58
+
47
59
func init () {
48
60
platform .Register (platform.Provider {
49
61
Name : "openstack" ,
@@ -159,86 +171,72 @@ func fetchConfigFromDevice(logger *log.Logger, ctx context.Context, path string)
159
171
return os .ReadFile (filepath .Join (mnt , configDriveUserdataPath ))
160
172
}
161
173
162
- func FindIPv6InterfaceName () (string , error ) {
174
+ // Checks if an IP address is IPv6
175
+ func isIPv6Address (ip net.IP ) bool {
176
+ isIPv6 := ip .To4 () == nil
177
+ fmt .Fprintf (os .Stdout , "Checking if IP is IPv6: %s, Result: %v\n " , ip .String (), isIPv6 )
178
+ return isIPv6
179
+ }
180
+
181
+ // Fetches the first valid IPv6 address
182
+ func findIPv6Address () (string , error ) {
183
+ fmt .Fprintln (os .Stdout , "Fetching network interfaces..." )
163
184
interfaces , err := net .Interfaces ()
164
185
if err != nil {
165
- return "" , err
186
+ return "" , fmt . Errorf ( "error fetching interfaces: %v" , err )
166
187
}
167
188
168
189
for _ , iface := range interfaces {
169
- // Check if the interface is up and not loopback
170
- if iface .Flags & net .FlagUp != 0 && iface .Flags & net .FlagLoopback == 0 {
171
- addrs , err := iface .Addrs ()
172
- if err != nil {
173
- continue
174
- }
190
+ fmt .Fprintf (os .Stdout , "Checking interface: %s\n " , iface .Name )
175
191
176
- for _ , addr := range addrs {
177
- // Check if the address is an IPv6
178
- if ipnet , ok := addr .(* net.IPNet ); ok && ipnet .IP .To4 () == nil && ! ipnet .IP .IsLinkLocalUnicast () {
179
- return iface .Name , nil
180
- }
181
- }
192
+ // Skip down interfaces
193
+ if iface .Flags & net .FlagUp == 0 || iface .Flags & net .FlagLoopback != 0 {
194
+ continue
182
195
}
183
- }
184
196
185
- return "" , fmt .Errorf ("no IPv6 interface name found" )
186
- }
187
-
188
- func fetchConfigFromMetadataService (f * resource.Fetcher ) ([]byte , error ) {
189
-
190
- // Find IPv6 name
191
- iface , err := FindIPv6InterfaceName ()
192
- if err != nil {
193
- return nil , err
194
- }
195
-
196
- // Construct URL
197
- var (
198
- ipv4MetadataServiceUrl = url.URL {
199
- Scheme : "http" ,
200
- Host : "169.254.169.254" ,
201
- Path : "openstack/latest/user_data" ,
202
- }
203
- ipv6MetadataServiceUrl = url.URL {
204
- Scheme : "http" ,
205
- Host : fmt .Sprintf ("[fe80::a9fe:a9fe%%%s]" , url .PathEscape (iface )),
206
- Path : "openstack/latest/user_data" ,
197
+ addrs , err := iface .Addrs ()
198
+ if err != nil {
199
+ fmt .Fprintf (os .Stdout , "Error fetching addresses for interface %s: %v\n " , iface .Name , err )
200
+ continue
207
201
}
208
- )
209
-
210
- var resIPv4 , resIPv6 []byte
211
- var errIPv4 , errIPv6 error
212
202
213
- // Try IPv4 endpoint
214
- resIPv4 , errIPv4 = f .FetchToBuffer (ipv4MetadataServiceUrl , resource.FetchOptions {})
215
- if errIPv4 != nil && errIPv4 != resource .ErrNotFound {
216
- f .Logger .Err ("Failed to fetch config from IPv4: %v" , errIPv4 )
203
+ for _ , addr := range addrs {
204
+ if ipnet , ok := addr .(* net.IPNet ); ok && isIPv6Address (ipnet .IP ) {
205
+ ipv6Address := fmt .Sprintf ("[%s]" , ipnet .IP .String ())
206
+ fmt .Fprintf (os .Stdout , "Found IPv6 address: %s on interface %s\n " , ipv6Address , iface .Name )
207
+ return ipv6Address , nil
208
+ }
209
+ }
217
210
}
211
+ return "" , fmt .Errorf ("no IPv6 address found" )
212
+ }
218
213
219
- // Try IPv6 endpoint
220
- resIPv6 , errIPv6 = f .FetchToBuffer (ipv6MetadataServiceUrl , resource.FetchOptions {})
221
- if errIPv6 != nil && errIPv6 != resource .ErrNotFound {
222
- f .Logger .Err ("Failed to fetch config from IPv6: %v" , errIPv6 )
214
+ // Fetches configuration from both IPv4 and IPv6 metadata services
215
+ func fetchConfigFromMetadataService (f * resource.Fetcher ) ([]byte , error ) {
216
+ fmt .Fprintln (os .Stdout , "Fetching from IPv4 metadata service..." )
217
+ ipv4Res , ipv4Err := f .FetchToBuffer (metadataServiceUrlIPv4 , resource.FetchOptions {})
218
+ if ipv4Err == nil {
219
+ fmt .Fprintln (os .Stdout , "Successfully fetched configuration from IPv4 metadata service." )
220
+ return ipv4Res , nil
223
221
}
222
+ fmt .Fprintf (os .Stdout , "IPv4 metadata service failed: %v\n " , ipv4Err )
224
223
225
- // If both IPv4 and IPv6 have valid data, combine them
226
- if resIPv4 != nil && resIPv6 != nil {
227
- return append (resIPv4 , resIPv6 ... ), nil
228
- } else if resIPv4 != nil {
229
- return resIPv4 , nil
230
- } else if resIPv6 != nil {
231
- return resIPv6 , nil
224
+ fmt .Fprintln (os .Stdout , "Fetching IPv6 address for metadata service..." )
225
+ ipv6Address , err := findIPv6Address ()
226
+ if err != nil {
227
+ f .Logger .Warning ("IPv6 metadata service lookup failed: %v" , err )
228
+ fmt .Fprintln (os .Stdout , "No IPv6 address found, returning IPv4 error." )
229
+ return nil , ipv4Err // Return the IPv4 error if no IPv6 is found
232
230
}
233
231
234
- // If both endpoints fail, return the appropriate error
235
- if errIPv4 != nil {
236
- return nil , errIPv4
237
- }
238
- if errIPv6 != nil {
239
- return nil , errIPv6
232
+ metadataServiceUrlIPv6 . Host = ipv6Address
233
+ fmt . Fprintf ( os . Stdout , "Fetching from IPv6 metadata service at %s... \n " , metadataServiceUrlIPv6 . String ())
234
+ ipv6Res , ipv6Err := f . FetchToBuffer ( metadataServiceUrlIPv6 , resource. FetchOptions {})
235
+ if ipv6Err != nil {
236
+ f . Logger . Warning ( "IPv6 metadata service failed: %v" , ipv6Err )
237
+ fmt . Fprintf ( os . Stdout , "IPv6 metadata service fetch failed: %v \n " , ipv6Err )
240
238
}
241
239
242
- // If both endpoints return ErrNotFound
243
- return nil , nil
240
+ fmt . Fprintln ( os . Stdout , "Returning response from IPv6 metadata service." )
241
+ return ipv6Res , ipv6Err
244
242
}
0 commit comments