From 573d87298707eae84f27fca9789d827736a7e181 Mon Sep 17 00:00:00 2001 From: Maysa Macedo Date: Mon, 14 Mar 2022 17:21:52 +0100 Subject: [PATCH] openstack: include support to metadata service In most cases, OpenStack metadata service is available in the cloud, which removes the requirement of config-drive. This patch will change the logic to try reading Metadata and Network data from the config-drive directory but if it's not present, it'll try to get it by safely fetching the URL. --- pkg/daemon/writer.go | 10 ++++ pkg/utils/utils_virtual.go | 107 ++++++++++++++++++++++++++----------- 2 files changed, 87 insertions(+), 30 deletions(-) diff --git a/pkg/daemon/writer.go b/pkg/daemon/writer.go index 6b3d9c2e0..22f949faa 100644 --- a/pkg/daemon/writer.go +++ b/pkg/daemon/writer.go @@ -43,6 +43,16 @@ func NewNodeStateStatusWriter(c snclientset.Interface, n string, f func()) *Node func (writer *NodeStateStatusWriter) Run(stop <-chan struct{}, refresh <-chan Message, syncCh chan<- struct{}, destDir string, runonce bool, platformType utils.PlatformType) { glog.V(0).Infof("Run(): start writer") msg := Message{} + + var err error + + if platformType == utils.VirtualOpenStack { + writer.metaData, writer.networkData, err = utils.GetOpenstackData() + if err != nil { + glog.Errorf("Run(): failed to get OpenStack data: %v", err) + } + } + if runonce { glog.V(0).Info("Run(): once") if err := writer.pollNicStatus(platformType); err != nil { diff --git a/pkg/utils/utils_virtual.go b/pkg/utils/utils_virtual.go index ba0d2d97a..f1e62a748 100644 --- a/pkg/utils/utils_virtual.go +++ b/pkg/utils/utils_virtual.go @@ -4,10 +4,12 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" + "os" "strconv" "github.com/golang/glog" + "github.com/hashicorp/go-retryablehttp" dputils "github.com/intel/sriov-network-device-plugin/pkg/utils" "github.com/jaypipes/ghw" sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1" @@ -42,9 +44,12 @@ var ( ) const ( - ospMetaDataDir = "/host/var/config/openstack/latest/" - ospNetworkData = ospMetaDataDir + "/network_data.json" - ospMetaData = ospMetaDataDir + "/meta_data.json" + ospMetaDataDir = "/host/var/config/openstack/2018-08-27" + ospMetaDataBaseUrl = "http://169.254.169.254/openstack/2018-08-27" + ospNetworkDataFile = ospMetaDataDir + "/network_data.json" + ospMetaDataFile = ospMetaDataDir + "/meta_data.json" + ospNetworkDataUrl = ospMetaDataBaseUrl + "/network_data.json" + ospMetaDataUrl = ospMetaDataBaseUrl + "/meta_data.json" ) // OSPMetaDataDevice -- Device structure within meta_data.json @@ -93,47 +98,89 @@ type OSPNetworkData struct { // Omit Services } -func metaData(platformType PlatformType, address string) (netFilter string, macAddress string) { - switch platformType { - case VirtualOpenStack: - metaData, networkData := readOpenstackMetaData() - netFilter, macAddress = parseOpenstackMetaData(address, metaData, networkData) - - default: - glog.V(2).Infof("Unknown PlatformType: %v", platformType) +// GetOpenstackData gets the metadata and network_data +func GetOpenstackData() (metaData *OSPMetaData, networkData *OSPNetworkData, err error) { + metaData, networkData, err = getOpenstackDataFromConfigDrive() + if err != nil { + metaData, networkData, err = getOpenstackDataFromMetadataService() } - - return + return metaData, networkData, err } -func readOpenstackMetaData() (metaData *OSPMetaData, networkData *OSPNetworkData) { +// getOpenstackDataFromConfigDrive reads the meta_data and network_data files +func getOpenstackDataFromConfigDrive() (metaData *OSPMetaData, networkData *OSPNetworkData, err error) { + metaData = &OSPMetaData{} networkData = &OSPNetworkData{} + glog.Infof("reading OpenStack meta_data from config-drive") + var metadataf *os.File + metadataf, err = os.Open(ospMetaDataFile) + if err != nil { + return metaData, networkData, fmt.Errorf("error opening file %s: %w", ospMetaDataFile, err) + } + defer func() { + if e := metadataf.Close(); err == nil && e != nil { + err = fmt.Errorf("error closing file %s: %w", ospMetaDataFile, e) + } + }() + if err = json.NewDecoder(metadataf).Decode(&metaData); err != nil { + return metaData, networkData, fmt.Errorf("error unmarshalling metadata from file %s: %w", ospMetaDataFile, err) + } - rawBytes, err := ioutil.ReadFile(ospNetworkData) + glog.Infof("reading OpenStack network_data from config-drive") + var networkDataf *os.File + networkDataf, err = os.Open(ospNetworkDataFile) if err != nil { - glog.Errorf("error reading file %s, %v", ospNetworkData, err) - return + return metaData, networkData, fmt.Errorf("error opening file %s: %w", ospNetworkDataFile, err) } + defer func() { + if e := networkDataf.Close(); err == nil && e != nil { + err = fmt.Errorf("error closing file %s: %w", ospNetworkDataFile, e) + } + }() + if err = json.NewDecoder(networkDataf).Decode(&networkData); err != nil { + return metaData, networkData, fmt.Errorf("error unmarshalling metadata from file %s: %w", ospNetworkDataFile, err) + } + return metaData, networkData, err +} - if err = json.Unmarshal(rawBytes, networkData); err != nil { - glog.Errorf("error unmarshalling raw bytes %v from %s", err, ospNetworkData) - return +func getBodyFromUrl(url string) ([]byte, error) { + glog.V(2).Infof("Getting body from %s", url) + resp, err := retryablehttp.Get(url) + if err != nil { + return nil, err + } + rawBytes, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err } + defer resp.Body.Close() + return rawBytes, nil +} +// getOpenstackDataFromMetadataService fetchs the metadata and network_data from the metadata service +func getOpenstackDataFromMetadataService() (metaData *OSPMetaData, networkData *OSPNetworkData, err error) { metaData = &OSPMetaData{} - - rawBytes, err = ioutil.ReadFile(ospMetaData) + networkData = &OSPNetworkData{} + glog.Infof("getting OpenStack meta_data from metadata server") + metaDataRawBytes, err := getBodyFromUrl(ospMetaDataUrl) if err != nil { - glog.Errorf("error reading file %s, %v", ospMetaData, err) - return + return metaData, networkData, fmt.Errorf("error getting OpenStack meta_data from %s: %v", ospMetaDataUrl, err) } - - if err = json.Unmarshal(rawBytes, metaData); err != nil { - glog.Errorf("error unmarshalling raw bytes %v from %s", err, ospNetworkData) - return + err = json.Unmarshal(metaDataRawBytes, metaData) + if err != nil { + return metaData, networkData, fmt.Errorf("error unmarshalling raw bytes %v from %s", err, ospMetaDataUrl) } - return + glog.Infof("getting OpenStack network_data from metadata server") + networkDataRawBytes, err := getBodyFromUrl(ospNetworkDataUrl) + if err != nil { + return metaData, networkData, fmt.Errorf("error getting OpenStack network_data from %s: %v", ospNetworkDataUrl, err) + } + err = json.Unmarshal(networkDataRawBytes, networkData) + if err != nil { + return metaData, networkData, fmt.Errorf("error unmarshalling raw bytes %v from %s", err, ospNetworkDataUrl) + } + return metaData, networkData, nil } func parseOpenstackMetaData(pciAddr string, metaData *OSPMetaData, networkData *OSPNetworkData) (networkID string, macAddress string) {