We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Passing AWS_PROFILE on update-kubeconfig cli
Add profile details if calling update passing update-kubeconfig with  profile details 

#aws eks update-kubeconfig --name k8s-test --kubeconfig k8s-test.config --profile myprofile 

Currently this generates as 
```
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - token
      - -i
      - k8s-test
      command: aws-iam-authenticator
```

Its good to add the profile details on the cli when not using default profile. 

```
- name: aws
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      command: aws-iam-authenticator
      args:
        - "token"
        - "-i"
        - "k8s-test"

      env:
        - name: AWS_PROFILE
          value: "myprofile"
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `awscli/customizations/eks/update_kubeconfig.py`
Content:
```
1 # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"). You
4 # may not use this file except in compliance with the License. A copy of
5 # the License is located at
6 #
7 # http://aws.amazon.com/apache2.0/
8 #
9 # or in the "license" file accompanying this file. This file is
10 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 # ANY KIND, either express or implied. See the License for the specific
12 # language governing permissions and limitations under the License.
13 
14 import os
15 import logging
16 
17 from botocore.compat import OrderedDict
18 
19 from awscli.customizations.commands import BasicCommand
20 from awscli.customizations.utils import uni_print
21 from awscli.compat import is_windows
22 from awscli.compat import which
23 from awscli.customizations.eks.exceptions import EKSClusterError
24 from awscli.customizations.eks.kubeconfig import (Kubeconfig,
25                                                   KubeconfigError,
26                                                   KubeconfigLoader,
27                                                   KubeconfigWriter,
28                                                   KubeconfigValidator,
29                                                   KubeconfigAppender)
30 from awscli.customizations.eks.ordered_yaml import ordered_yaml_dump
31 
32 LOG = logging.getLogger(__name__)
33 
34 DEFAULT_PATH = os.path.expanduser("~/.kube/config")
35 
36 # Use the endpoint for kubernetes 1.10
37 # To get the most recent endpoint we will need to
38 # Do a check on the cluster's version number
39 API_VERSION = "client.authentication.k8s.io/v1alpha1"
40 
41 AUTH_BIN = "aws-iam-authenticator"
42 
43 AUTH_GOGET_PATH = ("github.com/kubernetes-sigs/"
44                    "aws-iam-authenticator/cmd/aws-iam-authenticator")
45 
46 
47 def check_for_binary(binary):
48     return which(binary) is not None
49 
50 def warn_of_missing_dependencies():
51     """
52     Check the dependencies of the kubectl configuration generated by
53     update-kubeconfig to see if any are missing.
54     If they are missing, print a warning with information on how to download
55     the missing dependency
56 
57     Currently dependent on:
58     aws-iam-authenticator
59     """
60     if not check_for_binary(AUTH_BIN):
61         uni_print("Warning: {0} is not installed properly or is not in your path.\n"
62                   "Refer to the AWS Documentation to download it at "
63                   "https://docs.aws.amazon.com/eks/latest/userguide/configure-kubectl.html\n".format(AUTH_BIN))
64 
65 
66 class UpdateKubeconfigCommand(BasicCommand):
67     NAME = 'update-kubeconfig'
68 
69     DESCRIPTION = BasicCommand.FROM_FILE(
70         'eks',
71         'update-kubeconfig',
72         '_description.rst'
73     )
74 
75     ARG_TABLE = [
76         {
77             'name': 'name',
78             'help_text': ("The name of the cluster for which "
79                           "to create a kubeconfig entry. "
80                           "This cluster must exist in your account and in the "
81                           "specified or configured default Region "
82                           "for your AWS CLI installation."),
83             'required': True
84         },
85         {
86             'name': 'kubeconfig',
87             'help_text': ("Optionally specify a kubeconfig file to append "
88                           "with your configuration. "
89                           "By default, the configuration is written to the "
90                           "first file path in the KUBECONFIG "
91                           "environment variable (if it is set) "
92                           "or the default kubeconfig path (.kube/config) "
93                           "in your home directory."),
94             'required': False
95         },
96         {
97             'name': 'role-arn',
98             'help_text': ("To assume a role for cluster authentication, "
99                           "specify an IAM role ARN with this option. "
100                           "For example, if you created a cluster "
101                           "while assuming an IAM role, "
102                           "then you must also assume that role to "
103                           "connect to the cluster the first time."),
104             'required': False
105         },
106         {
107             'name': 'dry-run',
108             'action': 'store_true',
109             'default': False,
110             'help_text': ("Print the merged kubeconfig to stdout instead of "
111                           "writing it to the specified file."),
112             'required': False
113         },
114         {
115             'name': 'verbose',
116             'action': 'store_true',
117             'default': False,
118             'help_text': ("Print more detailed output "
119                           "when writing to the kubeconfig file, "
120                           "including the appended entries.")
121         }
122     ]
123 
124     def _display_entries(self, entries):
125         """ 
126         Display entries in yaml format
127 
128         :param entries: a list of OrderedDicts to be printed
129         :type entries: list
130         """
131         uni_print("Entries:\n\n")
132         for entry in entries:
133             uni_print(ordered_yaml_dump(entry))
134             uni_print("\n")
135 
136     def _run_main(self, parsed_args, parsed_globals):
137         client = EKSClient(self._session,
138                            parsed_args.name,
139                            parsed_args.role_arn,
140                            parsed_globals)
141         new_cluster_dict = client.get_cluster_entry()
142         new_user_dict = client.get_user_entry()
143 
144         config_selector = KubeconfigSelector(
145             os.environ.get("KUBECONFIG", ""),
146             parsed_args.kubeconfig
147         )
148         config = config_selector.choose_kubeconfig(
149             new_cluster_dict["name"]
150         )
151         updating_existing = config.has_cluster(new_cluster_dict["name"])
152         appender = KubeconfigAppender()
153         new_context_dict = appender.insert_cluster_user_pair(config,
154                                                              new_cluster_dict,
155                                                              new_user_dict)
156 
157         if parsed_args.dry_run:
158             uni_print(config.dump_content())
159         else:
160             writer = KubeconfigWriter()
161             writer.write_kubeconfig(config)
162 
163             if updating_existing:
164                 uni_print("Updated context {0} in {1}\n".format(
165                     new_context_dict["name"], config.path
166                 ))
167             else:
168                 uni_print("Added new context {0} to {1}\n".format(
169                     new_context_dict["name"], config.path
170                 ))
171 
172             if parsed_args.verbose:
173                 self._display_entries([
174                     new_context_dict,
175                     new_user_dict,
176                     new_cluster_dict
177                 ])
178 
179         warn_of_missing_dependencies()
180 
181 
182 class KubeconfigSelector(object):
183 
184     def __init__(self, env_variable, path_in, validator=None,
185                                               loader=None):
186         """
187         Parse KUBECONFIG into a list of absolute paths.
188         Also replace the empty list with DEFAULT_PATH
189 
190         :param env_variable: KUBECONFIG as a long string
191         :type env_variable: string
192 
193         :param path_in: The path passed in through the CLI
194         :type path_in: string or None
195         """
196         if validator is None:
197             validator = KubeconfigValidator()
198         self._validator = validator
199 
200         if loader is None:
201             loader = KubeconfigLoader(validator)
202         self._loader = loader
203 
204         if path_in is not None:
205             # Override environment variable
206             self._paths = [self._expand_path(path_in)]
207         else:
208             # Get the list of paths from the environment variable
209             if env_variable == "":
210                 env_variable = DEFAULT_PATH
211             self._paths = [self._expand_path(element)
212                            for element in env_variable.split(os.pathsep)
213                            if len(element.strip()) > 0]
214             if len(self._paths) == 0:
215                 self._paths = [DEFAULT_PATH]
216 
217     def choose_kubeconfig(self, cluster_name):
218         """
219         Choose which kubeconfig file to read from.
220         If name is already an entry in one of the $KUBECONFIG files,
221         choose that one.
222         Otherwise choose the first file.
223 
224         :param cluster_name: The name of the cluster which is going to be added
225         :type cluster_name: String
226 
227         :return: a chosen Kubeconfig based on above rules
228         :rtype: Kubeconfig
229         """
230         # Search for an existing entry to update
231         for candidate_path in self._paths:
232             try:
233                 loaded_config = self._loader.load_kubeconfig(candidate_path)
234 
235                 if loaded_config.has_cluster(cluster_name):
236                     LOG.debug("Found entry to update at {0}".format(
237                         candidate_path
238                     ))
239                     return loaded_config
240             except KubeconfigError as e:
241                 LOG.warning("Passing {0}:{1}".format(candidate_path, e))
242 
243         # No entry was found, use the first file in KUBECONFIG
244         #
245         # Note: This could raise KubeconfigErrors if paths[0] is corrupted
246         return self._loader.load_kubeconfig(self._paths[0])
247 
248     def _expand_path(self, path):
249         """ A helper to expand a path to a full absolute path. """
250         return os.path.abspath(os.path.expanduser(path))
251 
252 
253 class EKSClient(object):
254     def __init__(self, session, cluster_name, role_arn, parsed_globals=None):
255         self._session = session
256         self._cluster_name = cluster_name
257         self._role_arn = role_arn
258         self._cluster_description = None
259         self._globals = parsed_globals
260 
261     def _get_cluster_description(self):
262         """
263         Use an eks describe-cluster call to get the cluster description
264         Cache the response in self._cluster_description.
265         describe-cluster will only be called once.
266         """
267         if self._cluster_description is None:
268             if self._globals is None:
269                 client = self._session.create_client("eks")
270             else:
271                 client = self._session.create_client(
272                     "eks", 
273                     region_name=self._globals.region,
274                     endpoint_url=self._globals.endpoint_url,
275                     verify=self._globals.verify_ssl
276                 )
277             full_description = client.describe_cluster(name=self._cluster_name)
278             self._cluster_description = full_description["cluster"]
279 
280             if "status" not in self._cluster_description:
281                 raise EKSClusterError("Cluster not found")
282             if self._cluster_description["status"] != "ACTIVE":
283                 raise EKSClusterError("Cluster status not active")
284 
285         return self._cluster_description
286 
287     def get_cluster_entry(self):
288         """
289         Return a cluster entry generated using
290         the previously obtained description.
291         """
292 
293         cert_data = self._get_cluster_description().get("certificateAuthority",
294                                                         {"data": ""})["data"]
295         endpoint = self._get_cluster_description().get("endpoint")
296         arn = self._get_cluster_description().get("arn")
297 
298         return OrderedDict([
299             ("cluster", OrderedDict([
300                 ("certificate-authority-data", cert_data),
301                 ("server", endpoint)
302             ])),
303             ("name", arn)
304         ])
305 
306     def get_user_entry(self):
307         """
308         Return a user entry generated using
309         the previously obtained description.
310         """
311         generated_user = OrderedDict([
312             ("name", self._get_cluster_description().get("arn", "")),
313             ("user", OrderedDict([
314                 ("exec", OrderedDict([
315                     ("apiVersion", API_VERSION),
316                     ("args",
317                         [
318                             "token",
319                             "-i",
320                             self._cluster_name
321                         ]),
322                     ("command", AUTH_BIN)
323                 ]))
324             ]))
325         ])
326 
327         if is_windows:
328             generated_user["user"]["exec"]["command"] += ".exe"
329 
330         if self._role_arn is not None:
331             generated_user["user"]["exec"]["args"].extend([
332                 "-r",
333                 self._role_arn
334             ])
335 
336         return generated_user
337
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/awscli/customizations/eks/update_kubeconfig.py b/awscli/customizations/eks/update_kubeconfig.py
--- a/awscli/customizations/eks/update_kubeconfig.py
+++ b/awscli/customizations/eks/update_kubeconfig.py
@@ -333,4 +333,10 @@
                 self._role_arn
             ])
 
+        if self._session.profile:
+            generated_user["user"]["exec"]["env"] = [OrderedDict([
+                ("name", "AWS_PROFILE"),
+                ("value", self._session.profile)
+            ])]
+
         return generated_user

{"golden_diff": "diff --git a/awscli/customizations/eks/update_kubeconfig.py b/awscli/customizations/eks/update_kubeconfig.py\n--- a/awscli/customizations/eks/update_kubeconfig.py\n+++ b/awscli/customizations/eks/update_kubeconfig.py\n@@ -333,4 +333,10 @@\n                 self._role_arn\n             ])\n \n+        if self._session.profile:\n+            generated_user[\"user\"][\"exec\"][\"env\"] = [OrderedDict([\n+                (\"name\", \"AWS_PROFILE\"),\n+                (\"value\", self._session.profile)\n+            ])]\n+\n         return generated_user\n", "issue": "Passing AWS_PROFILE on update-kubeconfig cli\nAdd profile details if calling update passing update-kubeconfig with  profile details \r\n\r\n#aws eks update-kubeconfig --name k8s-test --kubeconfig k8s-test.config --profile myprofile \r\n\r\nCurrently this generates as \r\n```\r\n  user:\r\n    exec:\r\n      apiVersion: client.authentication.k8s.io/v1alpha1\r\n      args:\r\n      - token\r\n      - -i\r\n      - k8s-test\r\n      command: aws-iam-authenticator\r\n```\r\n\r\nIts good to add the profile details on the cli when not using default profile. \r\n\r\n```\r\n- name: aws\r\n  user:\r\n    exec:\r\n      apiVersion: client.authentication.k8s.io/v1alpha1\r\n      command: aws-iam-authenticator\r\n      args:\r\n        - \"token\"\r\n        - \"-i\"\r\n        - \"k8s-test\"\r\n\r\n      env:\r\n        - name: AWS_PROFILE\r\n          value: \"myprofile\"\r\n```\n", "before_files": [{"content": "# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n# http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\nimport os\nimport logging\n\nfrom botocore.compat import OrderedDict\n\nfrom awscli.customizations.commands import BasicCommand\nfrom awscli.customizations.utils import uni_print\nfrom awscli.compat import is_windows\nfrom awscli.compat import which\nfrom awscli.customizations.eks.exceptions import EKSClusterError\nfrom awscli.customizations.eks.kubeconfig import (Kubeconfig,\n                                                  KubeconfigError,\n                                                  KubeconfigLoader,\n                                                  KubeconfigWriter,\n                                                  KubeconfigValidator,\n                                                  KubeconfigAppender)\nfrom awscli.customizations.eks.ordered_yaml import ordered_yaml_dump\n\nLOG = logging.getLogger(__name__)\n\nDEFAULT_PATH = os.path.expanduser(\"~/.kube/config\")\n\n# Use the endpoint for kubernetes 1.10\n# To get the most recent endpoint we will need to\n# Do a check on the cluster's version number\nAPI_VERSION = \"client.authentication.k8s.io/v1alpha1\"\n\nAUTH_BIN = \"aws-iam-authenticator\"\n\nAUTH_GOGET_PATH = (\"github.com/kubernetes-sigs/\"\n                   \"aws-iam-authenticator/cmd/aws-iam-authenticator\")\n\n\ndef check_for_binary(binary):\n    return which(binary) is not None\n\ndef warn_of_missing_dependencies():\n    \"\"\"\n    Check the dependencies of the kubectl configuration generated by\n    update-kubeconfig to see if any are missing.\n    If they are missing, print a warning with information on how to download\n    the missing dependency\n\n    Currently dependent on:\n    aws-iam-authenticator\n    \"\"\"\n    if not check_for_binary(AUTH_BIN):\n        uni_print(\"Warning: {0} is not installed properly or is not in your path.\\n\"\n                  \"Refer to the AWS Documentation to download it at \"\n                  \"https://docs.aws.amazon.com/eks/latest/userguide/configure-kubectl.html\\n\".format(AUTH_BIN))\n\n\nclass UpdateKubeconfigCommand(BasicCommand):\n    NAME = 'update-kubeconfig'\n\n    DESCRIPTION = BasicCommand.FROM_FILE(\n        'eks',\n        'update-kubeconfig',\n        '_description.rst'\n    )\n\n    ARG_TABLE = [\n        {\n            'name': 'name',\n            'help_text': (\"The name of the cluster for which \"\n                          \"to create a kubeconfig entry. \"\n                          \"This cluster must exist in your account and in the \"\n                          \"specified or configured default Region \"\n                          \"for your AWS CLI installation.\"),\n            'required': True\n        },\n        {\n            'name': 'kubeconfig',\n            'help_text': (\"Optionally specify a kubeconfig file to append \"\n                          \"with your configuration. \"\n                          \"By default, the configuration is written to the \"\n                          \"first file path in the KUBECONFIG \"\n                          \"environment variable (if it is set) \"\n                          \"or the default kubeconfig path (.kube/config) \"\n                          \"in your home directory.\"),\n            'required': False\n        },\n        {\n            'name': 'role-arn',\n            'help_text': (\"To assume a role for cluster authentication, \"\n                          \"specify an IAM role ARN with this option. \"\n                          \"For example, if you created a cluster \"\n                          \"while assuming an IAM role, \"\n                          \"then you must also assume that role to \"\n                          \"connect to the cluster the first time.\"),\n            'required': False\n        },\n        {\n            'name': 'dry-run',\n            'action': 'store_true',\n            'default': False,\n            'help_text': (\"Print the merged kubeconfig to stdout instead of \"\n                          \"writing it to the specified file.\"),\n            'required': False\n        },\n        {\n            'name': 'verbose',\n            'action': 'store_true',\n            'default': False,\n            'help_text': (\"Print more detailed output \"\n                          \"when writing to the kubeconfig file, \"\n                          \"including the appended entries.\")\n        }\n    ]\n\n    def _display_entries(self, entries):\n        \"\"\" \n        Display entries in yaml format\n\n        :param entries: a list of OrderedDicts to be printed\n        :type entries: list\n        \"\"\"\n        uni_print(\"Entries:\\n\\n\")\n        for entry in entries:\n            uni_print(ordered_yaml_dump(entry))\n            uni_print(\"\\n\")\n\n    def _run_main(self, parsed_args, parsed_globals):\n        client = EKSClient(self._session,\n                           parsed_args.name,\n                           parsed_args.role_arn,\n                           parsed_globals)\n        new_cluster_dict = client.get_cluster_entry()\n        new_user_dict = client.get_user_entry()\n\n        config_selector = KubeconfigSelector(\n            os.environ.get(\"KUBECONFIG\", \"\"),\n            parsed_args.kubeconfig\n        )\n        config = config_selector.choose_kubeconfig(\n            new_cluster_dict[\"name\"]\n        )\n        updating_existing = config.has_cluster(new_cluster_dict[\"name\"])\n        appender = KubeconfigAppender()\n        new_context_dict = appender.insert_cluster_user_pair(config,\n                                                             new_cluster_dict,\n                                                             new_user_dict)\n\n        if parsed_args.dry_run:\n            uni_print(config.dump_content())\n        else:\n            writer = KubeconfigWriter()\n            writer.write_kubeconfig(config)\n\n            if updating_existing:\n                uni_print(\"Updated context {0} in {1}\\n\".format(\n                    new_context_dict[\"name\"], config.path\n                ))\n            else:\n                uni_print(\"Added new context {0} to {1}\\n\".format(\n                    new_context_dict[\"name\"], config.path\n                ))\n\n            if parsed_args.verbose:\n                self._display_entries([\n                    new_context_dict,\n                    new_user_dict,\n                    new_cluster_dict\n                ])\n\n        warn_of_missing_dependencies()\n\n\nclass KubeconfigSelector(object):\n\n    def __init__(self, env_variable, path_in, validator=None,\n                                              loader=None):\n        \"\"\"\n        Parse KUBECONFIG into a list of absolute paths.\n        Also replace the empty list with DEFAULT_PATH\n\n        :param env_variable: KUBECONFIG as a long string\n        :type env_variable: string\n\n        :param path_in: The path passed in through the CLI\n        :type path_in: string or None\n        \"\"\"\n        if validator is None:\n            validator = KubeconfigValidator()\n        self._validator = validator\n\n        if loader is None:\n            loader = KubeconfigLoader(validator)\n        self._loader = loader\n\n        if path_in is not None:\n            # Override environment variable\n            self._paths = [self._expand_path(path_in)]\n        else:\n            # Get the list of paths from the environment variable\n            if env_variable == \"\":\n                env_variable = DEFAULT_PATH\n            self._paths = [self._expand_path(element)\n                           for element in env_variable.split(os.pathsep)\n                           if len(element.strip()) > 0]\n            if len(self._paths) == 0:\n                self._paths = [DEFAULT_PATH]\n\n    def choose_kubeconfig(self, cluster_name):\n        \"\"\"\n        Choose which kubeconfig file to read from.\n        If name is already an entry in one of the $KUBECONFIG files,\n        choose that one.\n        Otherwise choose the first file.\n\n        :param cluster_name: The name of the cluster which is going to be added\n        :type cluster_name: String\n\n        :return: a chosen Kubeconfig based on above rules\n        :rtype: Kubeconfig\n        \"\"\"\n        # Search for an existing entry to update\n        for candidate_path in self._paths:\n            try:\n                loaded_config = self._loader.load_kubeconfig(candidate_path)\n\n                if loaded_config.has_cluster(cluster_name):\n                    LOG.debug(\"Found entry to update at {0}\".format(\n                        candidate_path\n                    ))\n                    return loaded_config\n            except KubeconfigError as e:\n                LOG.warning(\"Passing {0}:{1}\".format(candidate_path, e))\n\n        # No entry was found, use the first file in KUBECONFIG\n        #\n        # Note: This could raise KubeconfigErrors if paths[0] is corrupted\n        return self._loader.load_kubeconfig(self._paths[0])\n\n    def _expand_path(self, path):\n        \"\"\" A helper to expand a path to a full absolute path. \"\"\"\n        return os.path.abspath(os.path.expanduser(path))\n\n\nclass EKSClient(object):\n    def __init__(self, session, cluster_name, role_arn, parsed_globals=None):\n        self._session = session\n        self._cluster_name = cluster_name\n        self._role_arn = role_arn\n        self._cluster_description = None\n        self._globals = parsed_globals\n\n    def _get_cluster_description(self):\n        \"\"\"\n        Use an eks describe-cluster call to get the cluster description\n        Cache the response in self._cluster_description.\n        describe-cluster will only be called once.\n        \"\"\"\n        if self._cluster_description is None:\n            if self._globals is None:\n                client = self._session.create_client(\"eks\")\n            else:\n                client = self._session.create_client(\n                    \"eks\", \n                    region_name=self._globals.region,\n                    endpoint_url=self._globals.endpoint_url,\n                    verify=self._globals.verify_ssl\n                )\n            full_description = client.describe_cluster(name=self._cluster_name)\n            self._cluster_description = full_description[\"cluster\"]\n\n            if \"status\" not in self._cluster_description:\n                raise EKSClusterError(\"Cluster not found\")\n            if self._cluster_description[\"status\"] != \"ACTIVE\":\n                raise EKSClusterError(\"Cluster status not active\")\n\n        return self._cluster_description\n\n    def get_cluster_entry(self):\n        \"\"\"\n        Return a cluster entry generated using\n        the previously obtained description.\n        \"\"\"\n\n        cert_data = self._get_cluster_description().get(\"certificateAuthority\",\n                                                        {\"data\": \"\"})[\"data\"]\n        endpoint = self._get_cluster_description().get(\"endpoint\")\n        arn = self._get_cluster_description().get(\"arn\")\n\n        return OrderedDict([\n            (\"cluster\", OrderedDict([\n                (\"certificate-authority-data\", cert_data),\n                (\"server\", endpoint)\n            ])),\n            (\"name\", arn)\n        ])\n\n    def get_user_entry(self):\n        \"\"\"\n        Return a user entry generated using\n        the previously obtained description.\n        \"\"\"\n        generated_user = OrderedDict([\n            (\"name\", self._get_cluster_description().get(\"arn\", \"\")),\n            (\"user\", OrderedDict([\n                (\"exec\", OrderedDict([\n                    (\"apiVersion\", API_VERSION),\n                    (\"args\",\n                        [\n                            \"token\",\n                            \"-i\",\n                            self._cluster_name\n                        ]),\n                    (\"command\", AUTH_BIN)\n                ]))\n            ]))\n        ])\n\n        if is_windows:\n            generated_user[\"user\"][\"exec\"][\"command\"] += \".exe\"\n\n        if self._role_arn is not None:\n            generated_user[\"user\"][\"exec\"][\"args\"].extend([\n                \"-r\",\n                self._role_arn\n            ])\n\n        return generated_user\n", "path": "awscli/customizations/eks/update_kubeconfig.py"}], "after_files": [{"content": "# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n# http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\nimport os\nimport logging\n\nfrom botocore.compat import OrderedDict\n\nfrom awscli.customizations.commands import BasicCommand\nfrom awscli.customizations.utils import uni_print\nfrom awscli.compat import is_windows\nfrom awscli.compat import which\nfrom awscli.customizations.eks.exceptions import EKSClusterError\nfrom awscli.customizations.eks.kubeconfig import (Kubeconfig,\n                                                  KubeconfigError,\n                                                  KubeconfigLoader,\n                                                  KubeconfigWriter,\n                                                  KubeconfigValidator,\n                                                  KubeconfigAppender)\nfrom awscli.customizations.eks.ordered_yaml import ordered_yaml_dump\n\nLOG = logging.getLogger(__name__)\n\nDEFAULT_PATH = os.path.expanduser(\"~/.kube/config\")\n\n# Use the endpoint for kubernetes 1.10\n# To get the most recent endpoint we will need to\n# Do a check on the cluster's version number\nAPI_VERSION = \"client.authentication.k8s.io/v1alpha1\"\n\nAUTH_BIN = \"aws-iam-authenticator\"\n\nAUTH_GOGET_PATH = (\"github.com/kubernetes-sigs/\"\n                   \"aws-iam-authenticator/cmd/aws-iam-authenticator\")\n\n\ndef check_for_binary(binary):\n    return which(binary) is not None\n\ndef warn_of_missing_dependencies():\n    \"\"\"\n    Check the dependencies of the kubectl configuration generated by\n    update-kubeconfig to see if any are missing.\n    If they are missing, print a warning with information on how to download\n    the missing dependency\n\n    Currently dependent on:\n    aws-iam-authenticator\n    \"\"\"\n    if not check_for_binary(AUTH_BIN):\n        uni_print(\"Warning: {0} is not installed properly or is not in your path.\\n\"\n                  \"Refer to the AWS Documentation to download it at \"\n                  \"https://docs.aws.amazon.com/eks/latest/userguide/configure-kubectl.html\\n\".format(AUTH_BIN))\n\n\nclass UpdateKubeconfigCommand(BasicCommand):\n    NAME = 'update-kubeconfig'\n\n    DESCRIPTION = BasicCommand.FROM_FILE(\n        'eks',\n        'update-kubeconfig',\n        '_description.rst'\n    )\n\n    ARG_TABLE = [\n        {\n            'name': 'name',\n            'help_text': (\"The name of the cluster for which \"\n                          \"to create a kubeconfig entry. \"\n                          \"This cluster must exist in your account and in the \"\n                          \"specified or configured default Region \"\n                          \"for your AWS CLI installation.\"),\n            'required': True\n        },\n        {\n            'name': 'kubeconfig',\n            'help_text': (\"Optionally specify a kubeconfig file to append \"\n                          \"with your configuration. \"\n                          \"By default, the configuration is written to the \"\n                          \"first file path in the KUBECONFIG \"\n                          \"environment variable (if it is set) \"\n                          \"or the default kubeconfig path (.kube/config) \"\n                          \"in your home directory.\"),\n            'required': False\n        },\n        {\n            'name': 'role-arn',\n            'help_text': (\"To assume a role for cluster authentication, \"\n                          \"specify an IAM role ARN with this option. \"\n                          \"For example, if you created a cluster \"\n                          \"while assuming an IAM role, \"\n                          \"then you must also assume that role to \"\n                          \"connect to the cluster the first time.\"),\n            'required': False\n        },\n        {\n            'name': 'dry-run',\n            'action': 'store_true',\n            'default': False,\n            'help_text': (\"Print the merged kubeconfig to stdout instead of \"\n                          \"writing it to the specified file.\"),\n            'required': False\n        },\n        {\n            'name': 'verbose',\n            'action': 'store_true',\n            'default': False,\n            'help_text': (\"Print more detailed output \"\n                          \"when writing to the kubeconfig file, \"\n                          \"including the appended entries.\")\n        }\n    ]\n\n    def _display_entries(self, entries):\n        \"\"\" \n        Display entries in yaml format\n\n        :param entries: a list of OrderedDicts to be printed\n        :type entries: list\n        \"\"\"\n        uni_print(\"Entries:\\n\\n\")\n        for entry in entries:\n            uni_print(ordered_yaml_dump(entry))\n            uni_print(\"\\n\")\n\n    def _run_main(self, parsed_args, parsed_globals):\n        client = EKSClient(self._session,\n                           parsed_args.name,\n                           parsed_args.role_arn,\n                           parsed_globals)\n        new_cluster_dict = client.get_cluster_entry()\n        new_user_dict = client.get_user_entry()\n\n        config_selector = KubeconfigSelector(\n            os.environ.get(\"KUBECONFIG\", \"\"),\n            parsed_args.kubeconfig\n        )\n        config = config_selector.choose_kubeconfig(\n            new_cluster_dict[\"name\"]\n        )\n        updating_existing = config.has_cluster(new_cluster_dict[\"name\"])\n        appender = KubeconfigAppender()\n        new_context_dict = appender.insert_cluster_user_pair(config,\n                                                             new_cluster_dict,\n                                                             new_user_dict)\n\n        if parsed_args.dry_run:\n            uni_print(config.dump_content())\n        else:\n            writer = KubeconfigWriter()\n            writer.write_kubeconfig(config)\n\n            if updating_existing:\n                uni_print(\"Updated context {0} in {1}\\n\".format(\n                    new_context_dict[\"name\"], config.path\n                ))\n            else:\n                uni_print(\"Added new context {0} to {1}\\n\".format(\n                    new_context_dict[\"name\"], config.path\n                ))\n\n            if parsed_args.verbose:\n                self._display_entries([\n                    new_context_dict,\n                    new_user_dict,\n                    new_cluster_dict\n                ])\n\n        warn_of_missing_dependencies()\n\n\nclass KubeconfigSelector(object):\n\n    def __init__(self, env_variable, path_in, validator=None,\n                                              loader=None):\n        \"\"\"\n        Parse KUBECONFIG into a list of absolute paths.\n        Also replace the empty list with DEFAULT_PATH\n\n        :param env_variable: KUBECONFIG as a long string\n        :type env_variable: string\n\n        :param path_in: The path passed in through the CLI\n        :type path_in: string or None\n        \"\"\"\n        if validator is None:\n            validator = KubeconfigValidator()\n        self._validator = validator\n\n        if loader is None:\n            loader = KubeconfigLoader(validator)\n        self._loader = loader\n\n        if path_in is not None:\n            # Override environment variable\n            self._paths = [self._expand_path(path_in)]\n        else:\n            # Get the list of paths from the environment variable\n            if env_variable == \"\":\n                env_variable = DEFAULT_PATH\n            self._paths = [self._expand_path(element)\n                           for element in env_variable.split(os.pathsep)\n                           if len(element.strip()) > 0]\n            if len(self._paths) == 0:\n                self._paths = [DEFAULT_PATH]\n\n    def choose_kubeconfig(self, cluster_name):\n        \"\"\"\n        Choose which kubeconfig file to read from.\n        If name is already an entry in one of the $KUBECONFIG files,\n        choose that one.\n        Otherwise choose the first file.\n\n        :param cluster_name: The name of the cluster which is going to be added\n        :type cluster_name: String\n\n        :return: a chosen Kubeconfig based on above rules\n        :rtype: Kubeconfig\n        \"\"\"\n        # Search for an existing entry to update\n        for candidate_path in self._paths:\n            try:\n                loaded_config = self._loader.load_kubeconfig(candidate_path)\n\n                if loaded_config.has_cluster(cluster_name):\n                    LOG.debug(\"Found entry to update at {0}\".format(\n                        candidate_path\n                    ))\n                    return loaded_config\n            except KubeconfigError as e:\n                LOG.warning(\"Passing {0}:{1}\".format(candidate_path, e))\n\n        # No entry was found, use the first file in KUBECONFIG\n        #\n        # Note: This could raise KubeconfigErrors if paths[0] is corrupted\n        return self._loader.load_kubeconfig(self._paths[0])\n\n    def _expand_path(self, path):\n        \"\"\" A helper to expand a path to a full absolute path. \"\"\"\n        return os.path.abspath(os.path.expanduser(path))\n\n\nclass EKSClient(object):\n    def __init__(self, session, cluster_name, role_arn, parsed_globals=None):\n        self._session = session\n        self._cluster_name = cluster_name\n        self._role_arn = role_arn\n        self._cluster_description = None\n        self._globals = parsed_globals\n\n    def _get_cluster_description(self):\n        \"\"\"\n        Use an eks describe-cluster call to get the cluster description\n        Cache the response in self._cluster_description.\n        describe-cluster will only be called once.\n        \"\"\"\n        if self._cluster_description is None:\n            if self._globals is None:\n                client = self._session.create_client(\"eks\")\n            else:\n                client = self._session.create_client(\n                    \"eks\", \n                    region_name=self._globals.region,\n                    endpoint_url=self._globals.endpoint_url,\n                    verify=self._globals.verify_ssl\n                )\n            full_description = client.describe_cluster(name=self._cluster_name)\n            self._cluster_description = full_description[\"cluster\"]\n\n            if \"status\" not in self._cluster_description:\n                raise EKSClusterError(\"Cluster not found\")\n            if self._cluster_description[\"status\"] != \"ACTIVE\":\n                raise EKSClusterError(\"Cluster status not active\")\n\n        return self._cluster_description\n\n    def get_cluster_entry(self):\n        \"\"\"\n        Return a cluster entry generated using\n        the previously obtained description.\n        \"\"\"\n\n        cert_data = self._get_cluster_description().get(\"certificateAuthority\",\n                                                        {\"data\": \"\"})[\"data\"]\n        endpoint = self._get_cluster_description().get(\"endpoint\")\n        arn = self._get_cluster_description().get(\"arn\")\n\n        return OrderedDict([\n            (\"cluster\", OrderedDict([\n                (\"certificate-authority-data\", cert_data),\n                (\"server\", endpoint)\n            ])),\n            (\"name\", arn)\n        ])\n\n    def get_user_entry(self):\n        \"\"\"\n        Return a user entry generated using\n        the previously obtained description.\n        \"\"\"\n        generated_user = OrderedDict([\n            (\"name\", self._get_cluster_description().get(\"arn\", \"\")),\n            (\"user\", OrderedDict([\n                (\"exec\", OrderedDict([\n                    (\"apiVersion\", API_VERSION),\n                    (\"args\",\n                        [\n                            \"token\",\n                            \"-i\",\n                            self._cluster_name\n                        ]),\n                    (\"command\", AUTH_BIN)\n                ]))\n            ]))\n        ])\n\n        if is_windows:\n            generated_user[\"user\"][\"exec\"][\"command\"] += \".exe\"\n\n        if self._role_arn is not None:\n            generated_user[\"user\"][\"exec\"][\"args\"].extend([\n                \"-r\",\n                self._role_arn\n            ])\n\n        if self._session.profile:\n            generated_user[\"user\"][\"exec\"][\"env\"] = [OrderedDict([\n                (\"name\", \"AWS_PROFILE\"),\n                (\"value\", self._session.profile)\n            ])]\n\n        return generated_user\n", "path": "awscli/customizations/eks/update_kubeconfig.py"}]}