func()

in internal/system/appsdiscovery/apps_discovery.go [1038:1128]


func (d *SapDiscovery) discoverDatabaseSIDProfiles(ctx context.Context, sidUpper string, sidAdm string, abap bool) (string, error) {
	// No DB SID in userstore, check profiles
	profilePath := fmt.Sprintf("/usr/sap/%s/SYS/profile/*", sidUpper)
	result := d.Execute(ctx, commandlineexecutor.Params{
		Executable:  "sh",
		ArgsToSplit: `-c 'grep "dbid\|dbms/name\|j2ee/dbname\|dbs/hdb/dbname" ` + profilePath + `'`,
	})

	log.CtxLogger(ctx).Debugw("Profile grep output", "sid", sidUpper, "error", result.Error, "stdOut", result.StdOut, "stdErr", result.StdErr)

	if result.Error != nil {
		log.CtxLogger(ctx).Infow("Error retrieving sap profile info", "sid", sidUpper, "error", result.Error, "stdOut", result.StdOut, "stdErr", result.StdErr)
		return "", result.Error
	}

	re, err := regexp.Compile(`(dbid|dbms\/name|j2ee\/dbname|dbs\/hdb\/dbname)\s*=\s*([a-zA-Z][a-zA-Z0-9]{2})`)
	if err != nil {
		log.CtxLogger(ctx).Infow("Error compiling regex", "error", err)
		return "", err
	}
	matches := re.FindAllStringSubmatch(result.StdOut, -1)
	log.CtxLogger(ctx).Debugw("Profile grep matches", "sid", sidUpper, "matches", matches)
	var sidKey, sidValue string
	if len(matches) == 1 {
		log.CtxLogger(ctx).Debugw("Single match", "sid", sidUpper, "match", matches[0])
		match := matches[0]
		if len(match) > 2 {
			sidValue = match[2]
			log.CtxLogger(ctx).Debugw("Match", "sid", sidValue, "match", match)
		}
	} else if len(matches) > 1 {
		log.CtxLogger(ctx).Debugw("Multiple matches", "sid", sidUpper, "matches", matches)
		// Multiple matches, prioritize based on abap or Java
		// ABAP order: dbid, dbms/name, j2ee/dbname, dbs/hdb/dbname
		// Java order: j2ee/dbname, dbs/hdb/dbname, dbid, dbms/name
	matchLoop:
		for _, match := range matches {
			log.CtxLogger(ctx).Debugw("Match", "sid", sidUpper, "match", match)
			if len(match) > 2 {
				if abap {
					switch match[1] {
					case profileDBIDNameKey:
						sidValue = match[2]
						break matchLoop
					case profileDBMSNameKey:
						if sidValue == "" || sidKey == "j2ee/dbname" || sidKey == "dbs/hdb/dbname" {
							sidKey = match[1]
							sidValue = match[2]
						}
					case profileJ2EEDBNameKey:
						if sidValue == "" || sidKey == "dbs/hdb/dbname" {
							sidKey = match[1]
							sidValue = match[2]
						}
					case profileDBSHDBNameKey:
						if sidValue == "" {
							sidKey = match[1]
							sidValue = match[2]
						}
					}
				} else {
					switch match[1] {
					case profileJ2EEDBNameKey:
						sidValue = match[2]
						break matchLoop
					case profileDBSHDBNameKey:
						if sidValue == "" || sidKey == "dbid" || sidKey == "dbms/name" {
							sidKey = match[1]
							sidValue = match[2]
						}
					case profileDBIDNameKey:
						if sidValue == "" || sidKey == "dbms/name" {
							sidKey = match[1]
							sidValue = match[2]
						}
					case profileDBMSNameKey:
						if sidValue == "" {
							sidValue = match[2]
							sidKey = match[1]
						}
					}
				}
			}
		}
	}

	if sidValue == "" {
		return "", errors.New("No database SID found in profiles")
	}
	return sidValue, nil
}