@@ -44,6 +44,18 @@ const (
4444 configDriveUserdataPath = "/openstack/latest/user_data"
4545)
4646
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+
4759func init () {
4860 platform .Register (platform.Provider {
4961 Name : "openstack" ,
@@ -159,86 +171,72 @@ func fetchConfigFromDevice(logger *log.Logger, ctx context.Context, path string)
159171 return os .ReadFile (filepath .Join (mnt , configDriveUserdataPath ))
160172}
161173
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..." )
163184 interfaces , err := net .Interfaces ()
164185 if err != nil {
165- return "" , err
186+ return "" , fmt . Errorf ( "error fetching interfaces: %v" , err )
166187 }
167188
168189 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 )
175191
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
182195 }
183- }
184196
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
207201 }
208- )
209-
210- var resIPv4 , resIPv6 []byte
211- var errIPv4 , errIPv6 error
212202
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+ }
217210 }
211+ return "" , fmt .Errorf ("no IPv6 address found" )
212+ }
218213
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
223221 }
222+ fmt .Fprintf (os .Stdout , "IPv4 metadata service failed: %v\n " , ipv4Err )
224223
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
232230 }
233231
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 )
240238 }
241239
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
244242}
0 commit comments