@@ -10,6 +10,8 @@ import (
1010 "encoding/binary"
1111 "io"
1212 "net"
13+ "net/http"
14+ "strings"
1315 "time"
1416
1517 "github.com/pkg/errors"
@@ -37,6 +39,9 @@ const (
3739 hops = 0
3840 secs = 0
3941 flags = 0x8000 // Broadcast flag
42+
43+ nmAgentSupportedApisURL = "http://168.63.129.16/machine/plugins/?comp=nmagent&type=GetSupportedApis"
44+ dhcpRehydrationAPIStr = "SwiftV2DhcpRehydrationFromGoalState" // Set value provided by host
4045)
4146
4247// TransactionID represents a 4-byte DHCP transaction ID as defined in RFC 951,
4954 magicCookie = []byte {0x63 , 0x82 , 0x53 , 0x63 } // DHCP magic cookie
5055 DefaultReadTimeout = 3 * time .Second
5156 DefaultTimeout = 3 * time .Second
57+
58+ errResponseNotOK = errors .New ("not ok http status" )
5259)
5360
5461type DHCP struct {
@@ -459,3 +466,37 @@ func (c *DHCP) DiscoverRequest(ctx context.Context, mac net.HardwareAddr, ifname
459466 res := c .receiveDHCPResponse (ctx , reader , txid )
460467 return res
461468}
469+
470+ // DHCPRehydrationFeatureOnHost queries the host to check if a particular API is supported,
471+ // and if so, returns true; if we are unable to determine if the feature is enabled, an error
472+ // is returned
473+ func (c * DHCP ) DHCPRehydrationFeatureOnHost (ctx context.Context ) (bool , error ) {
474+ var (
475+ resp * http.Response
476+ httpClient = & http.Client {Timeout : DefaultTimeout }
477+ )
478+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , nmAgentSupportedApisURL , nil )
479+ if err != nil {
480+ return false , errors .Wrap (err , "failed to create http request" )
481+ }
482+ req .Header .Add ("Metadata" , "true" )
483+ req .Header .Add ("x-ms-version" , "2012-11-30" )
484+ resp , err = httpClient .Do (req )
485+ if err != nil {
486+ return false , errors .Wrap (err , "error issuing http request" )
487+ }
488+ defer resp .Body .Close ()
489+ if resp .StatusCode != http .StatusOK {
490+ return false , errResponseNotOK
491+ }
492+ bytes , err := io .ReadAll (resp .Body )
493+ if err != nil {
494+ return false , errors .Wrap (err , "failed to read response body" )
495+ }
496+ str := string (bytes )
497+ if ! strings .Contains (str , dhcpRehydrationAPIStr ) {
498+ return false , nil
499+ }
500+
501+ return true , nil
502+ }
0 commit comments