Skip to content

Commit 2fdc0fd

Browse files
committed
New config file format, added checks and a bit more documentation
1 parent 96e06d4 commit 2fdc0fd

File tree

7 files changed

+61
-57
lines changed

7 files changed

+61
-57
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Limes
22
Limes provides an easy work flow with MFA protected access keys, temporary credentials and access to multiple roles/accounts.
33

4-
Limes is a Local Instance MEtadata Service and emulates parts of the [AWS Instance Metadata Service](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) running on Amazon Linux. The AWS SDK and AWS CLI can therefor utilize this service to authenticate.
4+
Limes is the Local Instance MEtadata Service and emulates parts of the [AWS Instance Metadata Service](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) running on Amazon Linux. The AWS SDK and AWS CLI can therefor utilize this service to authenticate.
55

66
## Warning
77
The AWS SDK refreshes credentials automatically when using limes. So **all** services will change profile if the profile is changed in limes.
@@ -30,7 +30,7 @@ sudo ip link set dev lo:metadata up
3030
sudo /sbin/ifconfig lo0 alias 169.254.169.254
3131
```
3232

33-
#### Bash Completion
33+
## Bash Completion
3434

3535
##### Linux:
3636
```
@@ -39,7 +39,7 @@ wget -O /etc/bash_completion.d/limes https://raw.githubusercontent.com/otm/limes
3939

4040
##### Mac
4141
```
42-
wget -O $(brew --prefix)/etc/bash_completion.d/limes
42+
wget -O $(brew --prefix)/etc/bash_completion.d/limes https://raw.githubusercontent.com/otm/limes/master/assets/limes
4343
```
4444

4545
##### Fixing Completion for AWS CLI

cli-client.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,21 @@ func StartService(configFile, address, profileName, MFA string, port int, fake b
6767
log.Fatalf("Error reading config: %s\n", configErr.Error())
6868
}
6969

70-
configParseErr := yaml.Unmarshal(configContents, &config.profiles)
70+
configParseErr := yaml.Unmarshal(configContents, &config)
7171
if configParseErr != nil {
7272
log.Fatalf("Error in parsing config file: %s\n", configParseErr.Error())
7373
}
74+
75+
if len(config.Profiles) == 0 {
76+
log.Info("No profiles found, falling back to old config format.\n")
77+
configParseErr := yaml.Unmarshal(configContents, &config.Profiles)
78+
if configParseErr != nil {
79+
log.Fatalf("Error in parsing config file: %s\n", configParseErr.Error())
80+
}
81+
if len(config.Profiles) > 0 {
82+
log.Warning("WARNING: old depricated config format is used.\n")
83+
}
84+
}
7485
} else {
7586
log.Debug("No configuration file given\n")
7687
}
@@ -80,6 +91,14 @@ func StartService(configFile, address, profileName, MFA string, port int, fake b
8091
os.Remove(address)
8192
}()
8293

94+
if port == 0 {
95+
port = config.Port
96+
}
97+
98+
if port == 0 {
99+
port = 80
100+
}
101+
83102
// Startup the HTTP server and respond to requests.
84103
listener, err := net.ListenTCP("tcp", &net.TCPAddr{
85104
IP: net.ParseIP("169.254.169.254"),

cli-handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ func (h *CliHandler) RetrieveRole(ctx context.Context, in *pb.AssumeRoleRequest)
136136
// Config returns the current configuration
137137
func (h *CliHandler) Config(ctx context.Context, in *pb.Void) (*pb.ConfigReply, error) {
138138
res := &pb.ConfigReply{
139-
Profiles: make(map[string]*pb.Profile, len(h.config.profiles)),
139+
Profiles: make(map[string]*pb.Profile, len(h.config.Profiles)),
140140
}
141-
for name, profile := range h.config.profiles {
141+
for name, profile := range h.config.Profiles {
142142
res.Profiles[name] = &pb.Profile{
143143
AwsAccessKeyID: profile.AwsAccessKeyID,
144144
AwsSecretAccessKey: profile.AwsSecretAccessKey,

config.example

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,28 @@
11
---
2-
# The default profile is the profile that is loaded first, and the only role that
3-
# should need access keys. The default profile is *required*.
4-
#
5-
#
6-
# The default profile should only be able to assume roles. To assume these roles
7-
# the session should be authorized with a MFA token. With this set up your keys
8-
# will not be usable without multi factor authentication.
9-
default:
10-
# aws_access_key_id is required on the default profile
11-
aws_access_key_id: xxxxxxxxxxxxxxxxxxxx
12-
13-
# aws_secret_access_key is required on the default profile
14-
aws_secret_access_key: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
15-
16-
# role_session_name specifies the name used when assuming roles. Normaly a
17-
# sensible value is your username.
18-
role_session_name: yourusername
19-
20-
# region is used when connection to AWS and you can retrieve it from the
21-
# metadata service
22-
region: eu-west-1
23-
24-
# mfa_serial if present will prompt the user for an MFA when the service is
25-
# started. The MFA is then used for retrieving a session token.
26-
mfa_serial: arn:aws:iam::123456789012:mfa/yourusername
27-
28-
# This is an example of an profile that can be assumed with `limes profile admin`
29-
admin:
30-
# role_arn can be retrived from IAM
31-
role_arn: arn:aws:iam::123456789012:role/admin
32-
33-
# source_profile defines the profile to use when assuming this role
34-
source_profile: default
35-
36-
# protected controls if it is possible to assume the role for the metadata service
37-
# otherwise it is only possible to use with 'run' and 'env' subcommand
38-
protected: true
39-
region: eu-west-1
40-
41-
# This is an example of an profile that can be assumed with `limes profile readonly`
42-
readonly:
43-
role_arn: arn:aws:iam::123456789012:role/readonly
44-
source_profile: default
45-
region: eu-west-1
2+
port: 80
3+
profiles:
4+
# This defines a base profile, as it has AWS keys in it. Normaly a user like
5+
# this should only be allowd to assume other roles if MFA has been provided.
6+
# If an MFA serial is defined in the profile limes will promt for a MFA key
7+
# when needed.
8+
user:
9+
aws_access_key_id: xxxxxxxxxxxxxxxxxxxx
10+
aws_secret_access_key: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
11+
role_session_name: yourusername
12+
region: eu-west-1
13+
mfa_serial: arn:aws:iam::123456789012:mfa/yourusername
14+
15+
# This is an example of an profile that can not be assumed as
16+
# `protected: true` is defined on the profile. Only `limes run` and `limes env`
17+
# will be allowed.
18+
admin:
19+
role_arn: arn:aws:iam::123456789012:role/admin
20+
source_profile: user
21+
protected: true
22+
region: eu-west-1
23+
24+
# This is an example of an profile that can be assumed with `limes assume readonly`
25+
readonly:
26+
role_arn: arn:aws:iam::123456789012:role/readonly
27+
source_profile: user
28+
region: eu-west-1

config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ import (
1313

1414
// Config hold configuration read from the configuration file
1515
type Config struct {
16-
profiles Profiles
16+
Port int `yaml:"port"`
17+
Address string `yaml:"address"`
18+
Profiles
1719
}
1820

1921
// NewConfig returns a new Config struct
2022
func NewConfig() *Config {
2123
config := &Config{
22-
profiles: make(Profiles),
24+
Profiles: make(Profiles),
2325
}
2426

2527
return config

credentials-manager.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (m *CredentialsExpirationManager) SetSourceProfile(name, mfa string) error
125125
m.err = nil
126126

127127
log.Printf("Setting base profile: %v", name)
128-
profile, ok := m.config.profiles[name]
128+
profile, ok := m.config.Profiles[name]
129129
if !ok {
130130
m.err = errUnknownProfile
131131
if name != profileDefault {
@@ -202,7 +202,7 @@ func (m *CredentialsExpirationManager) Region() string {
202202
role = profileDefault
203203
}
204204

205-
profile, ok := m.config.profiles[role]
205+
profile, ok := m.config.Profiles[role]
206206
if !ok {
207207
fmt.Printf("FAiled to lookup: %v\n", role)
208208
return ""
@@ -227,7 +227,7 @@ func (m *CredentialsExpirationManager) Refresher() {
227227
// AssumeRole changes (assumes) the role `name`. An optional MFA can be passed
228228
// to the function, if set to "" the MFA is ignored
229229
func (m *CredentialsExpirationManager) AssumeRole(name, MFA string) error {
230-
profile, ok := m.config.profiles[name]
230+
profile, ok := m.config.Profiles[name]
231231
if !ok {
232232
return errUnknownProfile
233233
}
@@ -266,7 +266,7 @@ func (m *CredentialsExpirationManager) AssumeRole(name, MFA string) error {
266266
// RetrieveRole will assume and fetch temporary credentials, but does not update
267267
// the role and credentials stored by the manager.
268268
func (m *CredentialsExpirationManager) RetrieveRole(name, MFA string) (*AwsCredentials, error) {
269-
profile, ok := m.config.profiles[name]
269+
profile, ok := m.config.Profiles[name]
270270
if !ok {
271271
return nil, errUnknownProfile
272272
}

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ type Start struct {
7272
HelpFlag bool `flag:"h, help" description:"Display this message and exit"`
7373
Fake bool `flag:"fake" description:"Do not connect to AWS"`
7474
MFA string `option:"m, mfa" description:"MFA token to start up server"`
75-
Port int `option:"p, port" default:"80" description:"Port used by the metadata service"`
75+
Port int `option:"p, port" default:"" description:"Port used by the metadata service, default: 80"`
7676
}
7777

7878
// Stop defines the "stop" command cli flags and options

0 commit comments

Comments
 (0)