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 }