diff --git a/README.md b/README.md index 0ec2f18f7..d7fde6b37 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ systemctl restart kubelet.service ### Configure IAMIdentityMapping Custom Resource Definitions -In the `master` version of the AWS IAM Authenticator you can configure your users using one of three methods. The `mapUsers` and `mapRoles` as seen in the [Full Configuration Format](#full-configuration-format), using the new (alpha) [Kubernetes Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/), or using an [EKS aws-auth ConfigMap](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html). The `--backend-mode` flag determines which of these methods is enabled and their order of precedence (first one wins). The CRD and ConfigMap methods allow the authenticator server to always stay upto date with the latest allowed user. See [Issues #79](https://github.com/kubernetes-sigs/aws-iam-authenticator/issues/79) for more details. +In the `master` version of the AWS IAM Authenticator you can configure your users using one of three methods. The `mapUsers` and `mapRoles` as seen in the [Full Configuration Format](#full-configuration-format), using the new (alpha) [Kubernetes Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/), or using an [EKS aws-auth ConfigMap](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html). The `--backend-mode` flag determines which of these methods is enabled and their order of precedence (first match wins). The CRD and ConfigMap allow the authenticator server to update its IAM identity mappings without restarting. See [Issues #79](https://github.com/kubernetes-sigs/aws-iam-authenticator/issues/79) for more details. To setup an `IAMIdentityMapping` CRD you'll first need to `apply` the CRD manifest: diff --git a/pkg/mapper/configmap/configmap.go b/pkg/mapper/configmap/configmap.go index 2709c522f..d97f9ee60 100644 --- a/pkg/mapper/configmap/configmap.go +++ b/pkg/mapper/configmap/configmap.go @@ -47,49 +47,53 @@ func New(masterURL, kubeConfig string) (*MapStore, error) { // Starts a go routine which will watch the configmap and update the in memory data // when the values change. -func (ms *MapStore) startLoadConfigMap() { +func (ms *MapStore) startLoadConfigMap(stopCh <-chan struct{}) { go func() { for { - watcher, err := ms.configMap.Watch(metav1.ListOptions{ - Watch: true, - FieldSelector: fields.OneTermEqualSelector("metadata.name", "aws-auth").String(), - }) - if err != nil { - logrus.Warn("Unable to re-establish watch. Sleeping for 5 seconds") - time.Sleep(5 * time.Second) - continue - } - for r := range watcher.ResultChan() { - switch r.Type { - case watch.Error: - logrus.WithFields(logrus.Fields{"error": r}).Error("recieved a watch error") - case watch.Deleted: - logrus.Info("Resetting configmap on delete") - userMappings := make([]config.UserMapping, 0) - roleMappings := make([]config.RoleMapping, 0) - awsAccounts := make([]string, 0) - ms.saveMap(userMappings, roleMappings, awsAccounts) - case watch.Added, watch.Modified: - switch cm := r.Object.(type) { - case *core_v1.ConfigMap: - // TODO: Only watch on configmap/awsauth - if cm.Name != "aws-auth" { - break - } - logrus.Info("Received aws-auth watch event") - userMappings, roleMappings, awsAccounts, err := ms.parseMap(cm.Data) - if err != nil { - logrus.Errorf("There was an error parsing the config maps. Only saving data that was good, %+v", err) - } + select { + case <-stopCh: + return + default: + watcher, err := ms.configMap.Watch(metav1.ListOptions{ + Watch: true, + FieldSelector: fields.OneTermEqualSelector("metadata.name", "aws-auth").String(), + }) + if err != nil { + logrus.Warn("Unable to re-establish watch. Sleeping for 5 seconds") + time.Sleep(5 * time.Second) + continue + } + for r := range watcher.ResultChan() { + switch r.Type { + case watch.Error: + logrus.WithFields(logrus.Fields{"error": r}).Error("recieved a watch error") + case watch.Deleted: + logrus.Info("Resetting configmap on delete") + userMappings := make([]config.UserMapping, 0) + roleMappings := make([]config.RoleMapping, 0) + awsAccounts := make([]string, 0) ms.saveMap(userMappings, roleMappings, awsAccounts) - if err != nil { - logrus.Error(err) + case watch.Added, watch.Modified: + switch cm := r.Object.(type) { + case *core_v1.ConfigMap: + if cm.Name != "aws-auth" { + break + } + logrus.Info("Received aws-auth watch event") + userMappings, roleMappings, awsAccounts, err := ms.parseMap(cm.Data) + if err != nil { + logrus.Errorf("There was an error parsing the config maps. Only saving data that was good, %+v", err) + } + ms.saveMap(userMappings, roleMappings, awsAccounts) + if err != nil { + logrus.Error(err) + } } - } + } } + logrus.Error("Watch channel closed.") } - logrus.Error("Watch channel closed.") } }() } diff --git a/pkg/mapper/configmap/mapper.go b/pkg/mapper/configmap/mapper.go index 5fa9d2672..fce9014fb 100644 --- a/pkg/mapper/configmap/mapper.go +++ b/pkg/mapper/configmap/mapper.go @@ -25,9 +25,8 @@ func (m *ConfigMapMapper) Name() string { return mapper.ModeConfigMap } -func (m *ConfigMapMapper) Start(_ <-chan struct{}) error { - // TODO respect stopCh - m.startLoadConfigMap() +func (m *ConfigMapMapper) Start(stopCh <-chan struct{}) error { + m.startLoadConfigMap(stopCh) return nil }