agent/inventory/inventory.go (107 lines of code) (raw):

package inventory import ( "fmt" "strings" "github.com/aliyun/aliyun_assist_client/agent/inventory/gatherers" "github.com/aliyun/aliyun_assist_client/agent/inventory/model" "github.com/aliyun/aliyun_assist_client/agent/inventory/uploader" "github.com/aliyun/aliyun_assist_client/agent/log" "github.com/aliyun/aliyun_assist_client/agent/util" "github.com/aliyun/aliyun_assist_client/agent/util/jsonutil" "github.com/aliyun/aliyun_assist_client/agent/util/osutil" ) const ( errorMsgForMultipleAssociations = "%v detected multiple inventory configurations associated with one instance. Each instance can be associated with just one inventory configuration. Conflicting inventory configuration IDs: %v and %v" errorMsgForInvalidInventoryInput = "invalid or unrecognized input was received for %v plugin" errorMsgForExecutingInventoryViaAssociate = "%v plugin can only be invoked via oos-associate" errorMsgForUnableToDetectInvocationType = "it could not be detected if %v plugin was invoked via oos-associate because - %v" errorMsgForInabilityToSendDataToOOS = "inventory data could not be uploaded to server. Additional troubleshooting information - %v" msgWhenNoDataToReturnForInventoryPlugin = "Inventory policy has been successfully applied but there is no inventory data to upload to OOS" successfulMsgForInventoryPlugin = "Inventory policy has been successfully applied and collected inventory data has been uploaded to OOS" ) var ( windowsOnlyTypes = []string{"ACS:Service", "ACS:WindowsRole", "ACS:WindowsRegistry", "ACS:WindowsUpdate"} ) func RunGatherers(policy model.Policy) (items []model.Item, err error) { _, installedGatherers := gatherers.InitializeGatherers() applyGathererNames := collectGathererNames(policy) var applyGatherers []gatherers.T if len(applyGathererNames) > 0 { for _, applyGathererName := range applyGathererNames { if installedGatherers[applyGathererName] == nil { log.GetLogger().Errorf(errorMsgForUnableToDetectInvocationType, applyGathererName, "its not exist.") } else { applyGatherers = append(applyGatherers, installedGatherers[applyGathererName]) } } } log.GetLogger().Infof("apply inventory gatherers: %v", applyGathererNames) if len(applyGatherers) > 0 { for _, applyGatherer := range applyGatherers { gItems, err := applyGatherer.Run(policy.InventoryPolicy[applyGatherer.Name()]) if err == nil { items = append(items, gItems...) } else { log.GetLogger().WithError(err).Errorf("run gatherer %s fail", applyGatherer.Name()) } } } //check if there is data to send to OOS if len(items) == 0 { //no data to send to OOS - no need to call PutInventory API log.GetLogger().Info(msgWhenNoDataToReturnForInventoryPlugin) return } d, _ := jsonutil.Marshal(items) log.GetLogger().Debugf("Collected Inventory data: %v", string(d)) var inventoryUploader *uploader.InventoryUploader if inventoryUploader, err = uploader.NewInventoryUploader(util.GetInstanceId()); err != nil { err = fmt.Errorf("Unable to configure OOS Inventory uploader - %v", err.Error()) return } var optimizedInventoryItems, nonOptimizedInventoryItems []*model.InventoryItem if optimizedInventoryItems, nonOptimizedInventoryItems, err = inventoryUploader.ConvertToOOSInventoryItems(items); err != nil { err = fmt.Errorf("Encountered error in converting data to OOS InventoryItems - %v. Skipping upload to OOS", err.Error()) return } //first send data in optimized fashion if err = inventoryUploader.SendDataToOOS(util.GetInstanceId(), optimizedInventoryItems); err != nil { log.GetLogger().WithError(err).Error("failed to upload optimized inventory items") err = fmt.Errorf("Encountered error in sending data to OOS InventoryItems - %v", err.Error()) if shouldRetryWithNonOptimizedData(err) { //call putinventory again with non-optimized dataset if err = inventoryUploader.SendDataToOOS(util.GetInstanceId(), nonOptimizedInventoryItems); err != nil { log.GetLogger().WithError(err).Error("failed to upload nonOptimized inventory items") //sending non-optimized data also failed return } } return } return } func shouldRetryWithNonOptimizedData(err error) bool { msg := err.Error() if strings.Contains(msg, "Inventory.ItemContentMismatch") || strings.Contains(msg, "Inventory.InvalidItemContent") { log.GetLogger().Infof("%v encountered - will try sending nonOptimized inventory data", err.Error()) return true } return false } func supportByOs(gathererName string) bool { osType := osutil.GetOsType() for _, dataType := range windowsOnlyTypes { if dataType == gathererName && osType != osutil.OSWin { return false } } return true } func collectGathererNames(policy model.Policy) []string { var applyGatherNames []string for gathererName, config := range policy.InventoryPolicy { if config.Collection == "Enabled" { if supportByOs(gathererName) { applyGatherNames = append(applyGatherNames, gathererName) } else { log.GetLogger().Debugf("%s not supported by current os type %s, ignore", gathererName, osutil.GetOsType()) } } } return applyGatherNames }