github.com/mweagle/Sparta@v1.15.0/discovery.go (about)

     1  package sparta
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"fmt"
     7  	"os"
     8  
     9  	"github.com/sirupsen/logrus"
    10  )
    11  
    12  // Dynamically assigned discover function that is set by Main
    13  var discoverImpl func() (*DiscoveryInfo, error)
    14  
    15  var cachedDiscoveryInfo *DiscoveryInfo
    16  
    17  ////////////////////////////////////////////////////////////////////////////////
    18  // START - DiscoveryResource
    19  //
    20  
    21  // DiscoveryResource stores information about a CloudFormation resource
    22  // that the calling Go function `DependsOn`.
    23  type DiscoveryResource struct {
    24  	ResourceID   string
    25  	ResourceRef  string
    26  	ResourceType string
    27  	Properties   map[string]string
    28  }
    29  
    30  //
    31  // END - DiscoveryResource
    32  ////////////////////////////////////////////////////////////////////////////////
    33  
    34  ////////////////////////////////////////////////////////////////////////////////
    35  // START - DiscoveryInfo
    36  //
    37  
    38  // DiscoveryInfo encapsulates information returned by `sparta.Discovery()`
    39  // to enable a runtime function to discover information about its
    40  // AWS environment or resources that the function created explicit
    41  // `DependsOn` relationships
    42  type DiscoveryInfo struct {
    43  	// Current logical resource ID
    44  	ResourceID string
    45  	// Current AWS region
    46  	Region string
    47  	// Current Stack ID
    48  	StackID string
    49  	// StackName (eg, Sparta service name)
    50  	StackName string
    51  	// Map of resources this Go function has explicit `DependsOn` relationship
    52  	Resources map[string]DiscoveryResource
    53  }
    54  
    55  //
    56  // START - DiscoveryInfo
    57  ////////////////////////////////////////////////////////////////////////////////
    58  
    59  // Discover returns metadata information for resources upon which
    60  // the current golang lambda function depends. It's a reflection-based
    61  // pass-through to DiscoverByName
    62  func Discover() (*DiscoveryInfo, error) {
    63  	if nil == discoverImpl {
    64  		return nil, fmt.Errorf("discovery service has not been initialized")
    65  	}
    66  	return discoverImpl()
    67  }
    68  
    69  func initializeDiscovery(logger *logrus.Logger) {
    70  	// Setup the discoveryImpl reference
    71  	discoverImpl = func() (*DiscoveryInfo, error) {
    72  		// Cached info?
    73  		if cachedDiscoveryInfo != nil {
    74  			return cachedDiscoveryInfo, nil
    75  		}
    76  		// Initialize the cache
    77  		cachedDiscoveryInfo = &DiscoveryInfo{}
    78  
    79  		// Get the serialized discovery info the environment string
    80  		discoveryInfo := os.Getenv(envVarDiscoveryInformation)
    81  		decoded, decodedErr := base64.StdEncoding.DecodeString(discoveryInfo)
    82  		logger.WithFields(logrus.Fields{
    83  			"DecodeData":  string(decoded),
    84  			"DecodeError": decodedErr,
    85  		}).Debug("Decode result")
    86  		if decodedErr == nil {
    87  			// Unmarshal it...
    88  			unmarshalErr := json.Unmarshal(decoded, cachedDiscoveryInfo)
    89  			if unmarshalErr != nil {
    90  				logger.WithFields(logrus.Fields{
    91  					"Raw":           string(decoded),
    92  					"DiscoveryInfo": cachedDiscoveryInfo,
    93  					"Error":         unmarshalErr,
    94  				}).Error("Failed to unmarshal discovery info")
    95  			}
    96  			decodedErr = unmarshalErr
    97  		}
    98  		return cachedDiscoveryInfo, decodedErr
    99  	}
   100  }