Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // vertSplitter parses an AWS credentials file and splits the sections
- // up based on profiles. It then parses each section to build a
- // JSON profile struct for each profile including comments.
- package main
- import (
- "bufio"
- "encoding/json"
- "fmt"
- "os"
- "regexp"
- )
- // readFileAnchorChunks takes in input filename and regex string
- // it then reads the file and breaks the contents up in to a map of
- // indexed string slices based on the anchor provided. It's essentially
- // vertically splitting a file based on a regex separator.
- func readFileAnchorChunks(filename string, anchorRegex string) (chunks map[int][]string, err error) {
- chunks = make(map[int][]string)
- f, err := os.OpenFile(filename, os.O_RDONLY, os.ModeAppend)
- if err != nil {
- return chunks, err
- }
- scanner := bufio.NewScanner(f)
- reAnchor, err := regexp.Compile(anchorRegex)
- if err != nil {
- return chunks, err
- }
- var data []string
- for scanner.Scan() {
- data = append(data, scanner.Text())
- }
- // first find the anchor index points
- var anchors []int
- for index, line := range data {
- matchEntry := reAnchor.FindStringSubmatch(line)
- if len(matchEntry) > 0 {
- anchors = append(anchors, index)
- }
- }
- // now walk through the data between anchor lines
- for anchor, linenum := range anchors {
- if (anchor + 1) > len(anchors)-1 {
- // means we're at the last anchor and have to range differently
- for i := linenum; i <= len(data)-1; i++ {
- chunks[anchor] = append(chunks[anchor], data[i])
- }
- } else {
- for i := linenum; i <= anchors[anchor+1]-1; i++ {
- chunks[anchor] = append(chunks[anchor], data[i])
- }
- }
- }
- return chunks, err
- }
- func subExSingleFinder(line string, reOb *regexp.Regexp, matchGroup string) (resultSingle string, found bool) {
- match := reOb.FindStringSubmatch(line)
- found = false
- if len(match) > 0 {
- for i, name := range reOb.SubexpNames() {
- if i != 0 {
- if name == matchGroup {
- resultSingle = match[i]
- found = true
- return resultSingle, found
- }
- }
- }
- }
- return resultSingle, found
- }
- func loadProfileFile(filename string) (profiles []Profile, err error) {
- reProfileRString := `^\[(?P<profilename>.*)\]`
- chunks, err := readFileAnchorChunks(filename, reProfileRString)
- if err != nil {
- return profiles, err
- }
- for _, chunk := range chunks {
- // now that we have a pre-separated chunk we can assume it's
- // a new profile entry
- var p Profile
- for _, line := range chunk {
- reProfile := regexp.MustCompile(reProfileRString)
- reComment := regexp.MustCompile("^#(?P<comment>.*)")
- reOutput := regexp.MustCompile("^output = (?P<output>.*)")
- reRegion := regexp.MustCompile("^region = (?P<region>.*)")
- reAKID := regexp.MustCompile("^aws_access_key_id = (?P<akid>.*)")
- reSAK := regexp.MustCompile("^aws_secret_access_key = (?P<sak>.*)")
- reST := regexp.MustCompile("^aws_session_token = (?P<st>.*)")
- reRole := regexp.MustCompile(".*ASSUMED ROLE: (?P<rolearn>.*)")
- matchComment := reComment.FindStringSubmatch(line)
- if len(matchComment) > 0 {
- p.Comments = append(p.Comments, matchComment[0])
- }
- result, found := subExSingleFinder(line, reProfile, "profilename")
- if found {
- p.ProfileName = result
- }
- result, found = subExSingleFinder(line, reOutput, "output")
- if found {
- p.Output = result
- }
- result, found = subExSingleFinder(line, reRegion, "region")
- if found {
- p.Region = result
- }
- result, found = subExSingleFinder(line, reAKID, "akid")
- if found {
- p.AWSAccessKeyID = result
- }
- result, found = subExSingleFinder(line, reSAK, "sak")
- if found {
- p.AWSSecretAccessKey = result
- }
- result, found = subExSingleFinder(line, reST, "st")
- if found {
- p.AWSSessionToken = result
- }
- result, found = subExSingleFinder(line, reRole, "rolearn")
- if found {
- p.RoleArn = result
- }
- }
- profiles = append(profiles, p)
- }
- return profiles, err
- }
- // Profile is an object to hold a parsed profile
- // from an aws creds file
- type Profile struct {
- ProfileName string
- Comments []string
- Output string
- Region string
- AWSAccessKeyID string
- AWSSecretAccessKey string
- AWSSessionToken string
- RoleArn string
- }
- func main() {
- profiles, err := loadProfileFile("zSampleInput.txt")
- if err != nil {
- panic(err)
- }
- b, err := json.MarshalIndent(profiles, "", " ")
- if err != nil {
- panic(err)
- }
- fmt.Println(string(b))
- }
Add Comment
Please, Sign In to add comment