package deploy import ("context"; "strings"; "time") type CloudVenueProbe struct { CloudProvider, Environment, Workload, InstanceType, InstanceLifecycle, AvailabilityZone, OrganizationalUnit string; EC2Tags map[string]string `json:"ec2_tags,omitempty"` } var ec2IMDSReadVenue = readCloudVenueImpl func ReadCloudVenueProbe() *CloudVenueProbe { ctx,c:=context.WithTimeout(context.Background(),4*time.Second); defer c(); p,e:=ec2IMDSReadVenue(ctx); if e!=nil||p==nil{return nil}; return p } func readCloudVenueImpl(ctx context.Context) (*CloudVenueProbe, error) { token,err:=ec2IMDSToken(ctx); if err!=nil{return nil,err} it,err:=ec2IMDSFetch(ctx,token,"meta-data/instance-type"); if err!=nil||strings.TrimSpace(it)==""{return nil,err} p:=&CloudVenueProbe{CloudProvider:"aws",InstanceType:strings.TrimSpace(it),EC2Tags:map[string]string{}} if v,e:=ec2IMDSFetch(ctx,token,"meta-data/instance-life-cycle"); e==nil{p.InstanceLifecycle=strings.TrimSpace(v)} if v,e:=ec2IMDSFetch(ctx,token,"meta-data/placement/availability-zone"); e==nil{p.AvailabilityZone=strings.TrimSpace(v)} if keys,e:=ec2IMDSFetch(ctx,token,"meta-data/tags/instance"); e==nil{ for _,k:=range strings.Split(keys,"\n"){ k=strings.TrimSpace(k); if k==""{continue}; v,e:=ec2IMDSFetch(ctx,token,"meta-data/tags/instance/"+k); if e!=nil{continue}; v=strings.TrimSpace(v); p.EC2Tags[k]=v; if k=="Environment"{p.Environment=v}; if k=="Workload"{p.Workload=v} } } if ud,e:=ec2IMDSFetch(ctx,token,"user-data"); e==nil{ if ou:=parseOrganizationalUnit(ud); ou!=""{p.OrganizationalUnit=ou} } return p,nil } func parseOrganizationalUnit(userData string) string { for _,line:=range strings.Split(userData,"\n"){ line=strings.TrimSpace(line); if line==""||strings.HasPrefix(line,"#"){continue}; for _,pfx:=range []string{"organizational_unit=","aws:organizations:ou=","AETHERFORGE_OU=","ORGANIZATIONAL_UNIT="}{ if len(line)>=len(pfx)&&strings.EqualFold(line[:len(pfx)],pfx){return strings.TrimSpace(line[len(pfx):])} } }; return "" }