Last active
January 3, 2018 13:53
-
-
Save rendicott/7d511dc1caf6948178325f65631651c3 to your computer and use it in GitHub Desktop.
Parse a text file and split sections based on vertical anchors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[default] | |
output = json | |
region = us-east-1 | |
aws_access_key_id = BKIAIABOIDNONBVL987 | |
aws_secret_access_key = 78GisADFEk+knqq2ceGRYRTEERVVIumv7ZW | |
[dis-other-boi] | |
# This is that other account | |
output = json | |
region = us-east-1 | |
aws_access_key_id = ASIAIOIOVNOIWUEUFYA | |
aws_secret_access_key = vJVEREWB4Kaw/5Pl0DKWho+g1EfEFFDI0IOnw | |
aws_session_token = FQoDYXdzEDcaDPwyDDGStuhYrh6KBSLwAVJnpsF+36G9r2PCfT5KZNjVfLw7qXbnd6c1U0ZsV5+3rni/KSW8/5gW2ZkdN1gkO0ERnevergonnagiveyouupRoeqo4K7ycMlqibKo07An+fXjNx4wkTMTrceG3cE8zGeTL5LRJQh/GkoHFFFzD0DSuyFZJjXz56idF+HTi89yQH9NVCLvZz8KVyluvxObjfQW15QE0Yjl+gSFOnsqQe3iCPrOMWYkyyqPFDOtypsFcGG0KlreuycuGQPEub10n0xcu7kajotoRhQBZ3jkmO2Wk2RCjb+a/SBQ== | |
[dat-old-account] | |
# DO NOT EDIT | |
# GOSSAMER MANAGED SECTION | |
# (Will be overwritten regularly) | |
#################################################### | |
# ASSUMED ROLE: arn:aws:iam::790812376562953:role/cs/p-operations | |
# ASSUMED FROM INSTANCE ROLE: NA | |
# GENERATED: 2018-01-02 16:42:52.513969397 -0500 EST | |
# EXPIRES@2018-01-02 22:42:51 +0000 UTC | |
output = json | |
region = us-west-2 | |
aws_access_key_id = ASIAI6TATMY2YCE65J5Q | |
aws_secret_access_key = 82HwcMyftGhZxf+KM6HHuaaVTzRsqTPyNi1OU62d | |
aws_session_token = FQoDYXdzEDcaDINKwUQ4q6ts9XWIGiLwARg+RZM4hzkf59giN5sufa/K9+TOvk6TufnKXBeu467sWQ2BI3xmK1SBrvn2ufundcFud2LtyogO0lGyv8HJfJMc+BFEH/mzhPjudf0wYjGO+d0lOEj2knwnevergonnaletyoudown7pArq/WorFu0om24+gyFgXgc3fzkSVAE/WxAK3gGa18V8Uljj3ZL8JLBRYvMHrDTxw+WbQJ35NBMQ0o2/5DfBiD25znIuYmDXXqPLMmSN7WRiH2QNaPIzG6OwKbPrByvyQyaRMzKZAvGxbiu/syjb+a/SBQ== | |
[dat-new-account] | |
# DO NOT EDIT | |
# GOSSAMER MANAGED SECTION | |
# (Will be overwritten regularly) | |
#################################################### | |
# ASSUMED ROLE: arn:aws:iam::7815123567953:role/cs/p-operations | |
# ASSUMED FROM INSTANCE ROLE: NA | |
# GENERATED: 2018-01-02 16:46:40.704783754 -0500 EST | |
# EXPIRES@2018-01-02 22:46:40 +0000 UTC | |
output = json | |
region = us-east-2 | |
aws_access_key_id = ASIAAFEFVWEFQWXS4KVQ | |
aws_secret_access_key = MepbtEPH4EwLEopopamvoieDYJtKjruVU6YbNc | |
aws_session_token = FQoDYXdzEDcaDO5bzx2bPd8bCTdMAiLwAdjWobiKpismc5ybVEhSLbe1b0ADV6TSAugnRB7LrrSTT0TNIIAD1LBUC7swTHsMo0wCiwvLVynLaBefDEjQsRyi/IW7niJnallbymyself4K+PJIl912G+YNMDSoYMlyqd885qhYUJMH7G04DPKZWL0x8v0hr2gk73XaIOxcAAIkz12TEjk5ro4Y1f4wjcqUFO15CVM0CXiyYNTcxVZ4/Nm/kSHYCT9CSM67NULGf2jm+Ng9xijA+6/SBQ== | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"ProfileName": "default", | |
"Comments": null, | |
"Output": "json", | |
"Region": "us-east-1", | |
"AWSAccessKeyID": "BKIAIABOIDNONBVL987", | |
"AWSSecretAccessKey": "78GisADFEk+knqq2ceGRYRTEERVVIumv7ZW", | |
"AWSSessionToken": "", | |
"RoleArn": "" | |
}, | |
{ | |
"ProfileName": "dis-other-boi", | |
"Comments": [ | |
"# This is that other account" | |
], | |
"Output": "json", | |
"Region": "us-east-1", | |
"AWSAccessKeyID": "ASIAIOIOVNOIWUEUFYA", | |
"AWSSecretAccessKey": "vJVEREWB4Kaw/5Pl0DKWho+g1EfEFFDI0IOnw", | |
"AWSSessionToken": "FQoDYXdzEDcaDPwyDDGStuhYrh6KBSLwAVJnpsF+36G9r2PCfT5KZNjVfLw7qXbnd6c1U0ZsV5+3rni/KSW8/5gW2ZkdN1gkO0ERnevergonnagiveyouupRoeqo4K7ycMlqibKo07An+fXjNx4wkTMTrceG3cE8zGeTL5LRJQh/GkoHFFFzD0DSuyFZJjXz56idF+HTi89yQH9NVCLvZz8KVyluvxObjfQW15QE0Yjl+gSFOnsqQe3iCPrOMWYkyyqPFDOtypsFcGG0KlreuycuGQPEub10n0xcu7kajotoRhQBZ3jkmO2Wk2RCjb+a/SBQ==", | |
"RoleArn": "" | |
}, | |
{ | |
"ProfileName": "dat-old-account", | |
"Comments": [ | |
"# DO NOT EDIT", | |
"# GOSSAMER MANAGED SECTION", | |
"# (Will be overwritten regularly)", | |
"####################################################", | |
"# ASSUMED ROLE: arn:aws:iam::790812376562953:role/cs/p-operations", | |
"# ASSUMED FROM INSTANCE ROLE: NA", | |
"# GENERATED: 2018-01-02 16:42:52.513969397 -0500 EST", | |
"# EXPIRES@2018-01-02 22:42:51 +0000 UTC" | |
], | |
"Output": "json", | |
"Region": "us-west-2", | |
"AWSAccessKeyID": "ASIAI6TATMY2YCE65J5Q", | |
"AWSSecretAccessKey": "82HwcMyftGhZxf+KM6HHuaaVTzRsqTPyNi1OU62d", | |
"AWSSessionToken": "FQoDYXdzEDcaDINKwUQ4q6ts9XWIGiLwARg+RZM4hzkf59giN5sufa/K9+TOvk6TufnKXBeu467sWQ2BI3xmK1SBrvn2ufundcFud2LtyogO0lGyv8HJfJMc+BFEH/mzhPjudf0wYjGO+d0lOEj2knwnevergonnaletyoudown7pArq/WorFu0om24+gyFgXgc3fzkSVAE/WxAK3gGa18V8Uljj3ZL8JLBRYvMHrDTxw+WbQJ35NBMQ0o2/5DfBiD25znIuYmDXXqPLMmSN7WRiH2QNaPIzG6OwKbPrByvyQyaRMzKZAvGxbiu/syjb+a/SBQ==", | |
"RoleArn": "arn:aws:iam::790812376562953:role/cs/p-operations" | |
}, | |
{ | |
"ProfileName": "dat-new-account", | |
"Comments": [ | |
"# DO NOT EDIT", | |
"# GOSSAMER MANAGED SECTION", | |
"# (Will be overwritten regularly)", | |
"####################################################", | |
"# ASSUMED ROLE: arn:aws:iam::7815123567953:role/cs/p-operations", | |
"# ASSUMED FROM INSTANCE ROLE: NA", | |
"# GENERATED: 2018-01-02 16:46:40.704783754 -0500 EST", | |
"# EXPIRES@2018-01-02 22:46:40 +0000 UTC" | |
], | |
"Output": "json", | |
"Region": "us-east-2", | |
"AWSAccessKeyID": "ASIAAFEFVWEFQWXS4KVQ", | |
"AWSSecretAccessKey": "MepbtEPH4EwLEopopamvoieDYJtKjruVU6YbNc", | |
"AWSSessionToken": "FQoDYXdzEDcaDO5bzx2bPd8bCTdMAiLwAdjWobiKpismc5ybVEhSLbe1b0ADV6TSAugnRB7LrrSTT0TNIIAD1LBUC7swTHsMo0wCiwvLVynLaBefDEjQsRyi/IW7niJnallbymyself4K+PJIl912G+YNMDSoYMlyqd885qhYUJMH7G04DPKZWL0x8v0hr2gk73XaIOxcAAIkz12TEjk5ro4Y1f4wjcqUFO15CVM0CXiyYNTcxVZ4/Nm/kSHYCT9CSM67NULGf2jm+Ng9xijA+6/SBQ==", | |
"RoleArn": "arn:aws:iam::7815123567953:role/cs/p-operations" | |
} | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment