Guest User

Untitled

a guest
Jan 10th, 2018
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.32 KB | None | 0 0
  1. // vertSplitter parses an AWS credentials file and splits the sections
  2. // up based on profiles. It then parses each section to build a
  3. // JSON profile struct for each profile including comments.
  4.  
  5. package main
  6.  
  7. import (
  8. "bufio"
  9. "encoding/json"
  10. "fmt"
  11. "os"
  12. "regexp"
  13. )
  14.  
  15. // readFileAnchorChunks takes in input filename and regex string
  16. // it then reads the file and breaks the contents up in to a map of
  17. // indexed string slices based on the anchor provided. It's essentially
  18. // vertically splitting a file based on a regex separator.
  19. func readFileAnchorChunks(filename string, anchorRegex string) (chunks map[int][]string, err error) {
  20. chunks = make(map[int][]string)
  21. f, err := os.OpenFile(filename, os.O_RDONLY, os.ModeAppend)
  22. if err != nil {
  23. return chunks, err
  24. }
  25. scanner := bufio.NewScanner(f)
  26. reAnchor, err := regexp.Compile(anchorRegex)
  27. if err != nil {
  28. return chunks, err
  29. }
  30. var data []string
  31. for scanner.Scan() {
  32. data = append(data, scanner.Text())
  33. }
  34. // first find the anchor index points
  35. var anchors []int
  36. for index, line := range data {
  37. matchEntry := reAnchor.FindStringSubmatch(line)
  38. if len(matchEntry) > 0 {
  39. anchors = append(anchors, index)
  40. }
  41. }
  42. // now walk through the data between anchor lines
  43. for anchor, linenum := range anchors {
  44. if (anchor + 1) > len(anchors)-1 {
  45. // means we're at the last anchor and have to range differently
  46. for i := linenum; i <= len(data)-1; i++ {
  47. chunks[anchor] = append(chunks[anchor], data[i])
  48. }
  49. } else {
  50. for i := linenum; i <= anchors[anchor+1]-1; i++ {
  51. chunks[anchor] = append(chunks[anchor], data[i])
  52. }
  53. }
  54. }
  55. return chunks, err
  56. }
  57.  
  58. func subExSingleFinder(line string, reOb *regexp.Regexp, matchGroup string) (resultSingle string, found bool) {
  59. match := reOb.FindStringSubmatch(line)
  60. found = false
  61. if len(match) > 0 {
  62. for i, name := range reOb.SubexpNames() {
  63. if i != 0 {
  64. if name == matchGroup {
  65. resultSingle = match[i]
  66. found = true
  67. return resultSingle, found
  68. }
  69. }
  70. }
  71. }
  72. return resultSingle, found
  73. }
  74.  
  75. func loadProfileFile(filename string) (profiles []Profile, err error) {
  76. reProfileRString := `^\[(?P<profilename>.*)\]`
  77. chunks, err := readFileAnchorChunks(filename, reProfileRString)
  78. if err != nil {
  79. return profiles, err
  80. }
  81. for _, chunk := range chunks {
  82. // now that we have a pre-separated chunk we can assume it's
  83. // a new profile entry
  84. var p Profile
  85. for _, line := range chunk {
  86. reProfile := regexp.MustCompile(reProfileRString)
  87. reComment := regexp.MustCompile("^#(?P<comment>.*)")
  88. reOutput := regexp.MustCompile("^output = (?P<output>.*)")
  89. reRegion := regexp.MustCompile("^region = (?P<region>.*)")
  90. reAKID := regexp.MustCompile("^aws_access_key_id = (?P<akid>.*)")
  91. reSAK := regexp.MustCompile("^aws_secret_access_key = (?P<sak>.*)")
  92. reST := regexp.MustCompile("^aws_session_token = (?P<st>.*)")
  93. reRole := regexp.MustCompile(".*ASSUMED ROLE: (?P<rolearn>.*)")
  94. matchComment := reComment.FindStringSubmatch(line)
  95. if len(matchComment) > 0 {
  96. p.Comments = append(p.Comments, matchComment[0])
  97. }
  98. result, found := subExSingleFinder(line, reProfile, "profilename")
  99. if found {
  100. p.ProfileName = result
  101. }
  102. result, found = subExSingleFinder(line, reOutput, "output")
  103. if found {
  104. p.Output = result
  105. }
  106. result, found = subExSingleFinder(line, reRegion, "region")
  107. if found {
  108. p.Region = result
  109. }
  110. result, found = subExSingleFinder(line, reAKID, "akid")
  111. if found {
  112. p.AWSAccessKeyID = result
  113. }
  114. result, found = subExSingleFinder(line, reSAK, "sak")
  115. if found {
  116. p.AWSSecretAccessKey = result
  117. }
  118. result, found = subExSingleFinder(line, reST, "st")
  119. if found {
  120. p.AWSSessionToken = result
  121. }
  122. result, found = subExSingleFinder(line, reRole, "rolearn")
  123. if found {
  124. p.RoleArn = result
  125. }
  126. }
  127. profiles = append(profiles, p)
  128. }
  129. return profiles, err
  130. }
  131.  
  132. // Profile is an object to hold a parsed profile
  133. // from an aws creds file
  134. type Profile struct {
  135. ProfileName string
  136. Comments []string
  137. Output string
  138. Region string
  139. AWSAccessKeyID string
  140. AWSSecretAccessKey string
  141. AWSSessionToken string
  142. RoleArn string
  143. }
  144.  
  145. func main() {
  146. profiles, err := loadProfileFile("zSampleInput.txt")
  147. if err != nil {
  148. panic(err)
  149. }
  150. b, err := json.MarshalIndent(profiles, "", " ")
  151. if err != nil {
  152. panic(err)
  153. }
  154. fmt.Println(string(b))
  155.  
  156. }
Add Comment
Please, Sign In to add comment