aws.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package cloudutil
  2. import (
  3. "strings"
  4. "unicode"
  5. "github.com/kubecost/cost-model/pkg/log"
  6. )
  7. // ConvertToGlueColumnFormat takes a string and runs through various regex
  8. // and string replacement statements to convert it to a format compatible
  9. // with AWS Glue and Athena column names.
  10. // Following guidance from AWS provided here ('Column Names' section):
  11. // https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/run-athena-sql.html
  12. // It returns a string containing the column name in proper column name format and length.
  13. func ConvertToGlueColumnFormat(columnName string) string {
  14. var sb strings.Builder
  15. var prev rune
  16. for i, r := range columnName {
  17. if unicode.IsUpper(r) && prev != '_' && i != 0 {
  18. sb.WriteRune('_')
  19. }
  20. if !unicode.IsLetter(r) && !unicode.IsNumber(r) && prev != '_' && i != 0 && i != (len(columnName)-1) {
  21. sb.WriteRune('_')
  22. prev = '_'
  23. continue
  24. }
  25. if r == '_' {
  26. if prev == '_' || i == 0 || i == len(columnName)-1 {
  27. continue
  28. }
  29. }
  30. sb.WriteRune(unicode.ToLower(r))
  31. prev = r
  32. }
  33. final := sb.String()
  34. // Longer column name than expected - remove _ left to right
  35. allowedColLen := 128
  36. underscoreToRemove := len(final) - allowedColLen
  37. if underscoreToRemove > 0 {
  38. final = strings.Replace(final, "_", "", underscoreToRemove)
  39. }
  40. // If removing all of the underscores still didn't
  41. // make the column name < 128 characters, trim it!
  42. if len(final) > allowedColLen {
  43. final = final[:allowedColLen]
  44. }
  45. log.Debugf("Column name being returned: \"%s\". Length: \"%d\".", final, len(final))
  46. return final
  47. }