Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new template variable {{EC2PrivateDNSName}} #65

Merged

Conversation

nckturner
Copy link
Contributor

@nckturner nckturner commented Mar 27, 2018

  • kubelet reports itself as system:node:<aws-private-dns>
  • modifies authenticator to be able to discover an ec2 instance's private dns
    and use it for the node name when {{EC2PrivateDNSName}} is used in the
    template username
  • allows a role to be specified in the config file to assume for the describe
    instances call, in case it is in a separate account.

Fixes: #57
Alternative to: #61

Signed-off-by: Nick Turner nic@amazon.com

Copy link
Contributor

@mattlandis mattlandis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like this approach better. It allows for more extensiblity and limits the number of mapping types to deal with.

Just a couple minor comments. None of them are blockers to me. If you don't want to make the change to handle malformed usernames in the PR please create an issue.

template = strings.Replace(template, "{{SessionName}}", sessionName, -1)
return template

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since usernames must be DNS-1123 compliant should we have a final check to ensure the rendered template is valid and return an error if it is not? For instance if I accidentally put in {{AccountId}} instead of {{AccountID}} it will not get replaced and we will return an invalid username to k8s.

}
}
if privateDNSName == "" {
return "", errors.New(fmt.Sprintf("failed to find node %s", id))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use fmt.Errorf here.

return template, nil
}

type EC2Provider interface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be local scope.

@mattlandis
Copy link
Contributor

Also can we open two issues

  1. add metrics for this since it is a place latency could be introduced
  2. Examine managing cache lifetime so that it won't be an issue for long running clusters with frequent node changes


// Private DNS requires EC2 API call
if strings.Contains(template, "{{EC2PrivateDNSName}}") {
re := regexp.MustCompile("^i-(\\w{8}|\\w{17})$")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen (^i-(\w{8}|\w{17})$)|(^mi-\w{17}$) used elsewhere. EC2 apparently also has managed instances for hybrid environments with "mi-" id prefix. Not sure if these should be allowed or not (are they covered by getPrivateDNSName?).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbenhur Let's open a issue for this. I think it requires more investigation to make sure there are no other side effects we aren't thinking about.

@nckturner Add the sign-off and I think this is good to go.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, will rebase and sign off.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd also be fine to do minimal validation here and just trust that ec2:DescribeInstances is going to return an appropriate error if the instance ID is invalid.

We could also stick this regex in a global var instanceIDPattern = regexp.MustCompile(...) so we only compile once at init.

@nckturner nckturner force-pushed the kubelet-username-templatized branch from 5ad7b14 to 00bca85 Compare March 27, 2018 20:41
Copy link
Contributor

@mattmoyer mattmoyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small comments but LGTM. Thanks!

README.md Outdated
@@ -173,6 +173,9 @@ server:
# output `path` where a generated webhook kubeconfig will be stored.
generateKubeconfig: /etc/kubernetes/heptio-authenticator-aws.kubeconfig # (default)

# role to assume before querying EC2 API in order to discover metadata like EC2 private DNS Name
defaultEC2DescribeInstancesRoleARN: arn:aws:iam::000000000000:role/DescribeInstancesRole
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the "default" part here is slightly confusing to me. Maybe something like serverAssumeRoleARN?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, default is incorrect now. I like having EC2DescribeInstances in the name though, as I think it helps differentiate it from the other references to roles. How about serverEC2DescribeInstancesRoleARN?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I like that.

@@ -29,4 +29,7 @@ const (

// certLifetime is the lifetime of the CA certificate (100 years)
certLifetime = time.Hour * 24 * 365 * 100

// nodeNamePrefix is the username prefix that the apiserver expects of kubelet
NodeNamePrefix = "system:node:"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer needed as far as I can tell.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

groups = append(groups, group)
}
return username, groups, nil
} else if userMapping, exists := h.lowercaseUserMap[arn]; exists {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: these else if clauses could now be plain if clauses since we return early at the end of each one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


// Private DNS requires EC2 API call
if strings.Contains(template, "{{EC2PrivateDNSName}}") {
re := regexp.MustCompile("^i-(\\w{8}|\\w{17})$")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd also be fine to do minimal validation here and just trust that ec2:DescribeInstances is going to return an appropriate error if the instance ID is invalid.

We could also stick this regex in a global var instanceIDPattern = regexp.MustCompile(...) so we only compile once at init.

template = strings.Replace(template, "{{SessionName}}", sessionName, -1)
return template
re := regexp.MustCompile("[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same note here re: using a global var dns1123Pattern = regexp.MustCompile(...) compiled at init.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to global.

@nckturner nckturner force-pushed the kubelet-username-templatized branch from 14d4f73 to 30b4923 Compare March 27, 2018 21:22
…te DNS

- kubelet reports itself as system:node:<aws-private-dns>
- modifies authenticator to be able to discover an ec2 instance's private dns
  and use it for the node name when {{EC2PrivateDNSName}} is used in the
  template username
- allows a role to be specified in the config file to assume for the describe
  instances call, in case it is in a separate account.

Signed-off-by: Nick Turner <nic@amazon.com>
@nckturner nckturner force-pushed the kubelet-username-templatized branch from 30b4923 to 9e6702c Compare March 27, 2018 21:31
@nckturner
Copy link
Contributor Author

Squashed review commit.

@nckturner nckturner merged commit bdea007 into kubernetes-sigs:master Mar 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants