def test_merge_credentials_already_present(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'clusters': [ 'cluster1', 'cluster2' ], 'contexts': [ 'context1', 'context2' ], 'users': [ 'user1', 'user2' ], 'current-context': 'cluster1', } with open(existing.name, 'w+') as stream: yaml.dump(obj1, stream) obj2 = { 'clusters': [ 'cluster2' ], 'contexts': [ 'context2' ], 'users': [ 'user2' ], 'current-context': 'cluster2', } with open(addition.name, 'w+') as stream: yaml.dump(obj2, stream) merge_kubernetes_configurations(existing.name, addition.name) self.addCleanup(os.remove, addition.name) with open(existing.name, 'r') as stream: merged = yaml.load(stream) self.addCleanup(os.remove, existing.name) self.assertEqual(len(merged['clusters']), 2) self.assertEqual(merged['clusters'], ['cluster1', 'cluster2']) self.assertEqual(len(merged['contexts']), 2) self.assertEqual(merged['contexts'], ['context1', 'context2']) self.assertEqual(len(merged['users']), 2) self.assertEqual(merged['users'], ['user1', 'user2']) self.assertEqual(merged['current-context'], obj2['current-context'])
def test_merge_credentials_already_present(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'clusters': ['cluster1', 'cluster2'], 'contexts': ['context1', 'context2'], 'users': ['user1', 'user2'], 'current-context': 'cluster1', } with open(existing.name, 'w+') as stream: yaml.dump(obj1, stream) obj2 = { 'clusters': ['cluster2'], 'contexts': ['context2'], 'users': ['user2'], 'current-context': 'cluster2', } with open(addition.name, 'w+') as stream: yaml.dump(obj2, stream) merge_kubernetes_configurations(existing.name, addition.name) self.addCleanup(os.remove, addition.name) with open(existing.name, 'r') as stream: merged = yaml.load(stream) self.addCleanup(os.remove, existing.name) self.assertEqual(len(merged['clusters']), 2) self.assertEqual(merged['clusters'], ['cluster1', 'cluster2']) self.assertEqual(len(merged['contexts']), 2) self.assertEqual(merged['contexts'], ['context1', 'context2']) self.assertEqual(len(merged['users']), 2) self.assertEqual(merged['users'], ['user1', 'user2']) self.assertEqual(merged['current-context'], obj2['current-context'])
def test_merge_credentials_already_present(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'clusters': [{ 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://cluster1-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster1' }, { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://cluster2-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster2' }], 'contexts': [{ 'context': { 'cluster': 'cluster1', 'user': '******' }, 'name': 'context1' }, { 'context': { 'cluster': 'cluster1', 'user': '******' }, 'name': 'context2' }], 'users': [{ 'name': 'cluster1User_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token2' } }, { 'name': 'cluster2User_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token2' } }], 'current-context': 'context1', } with open(existing.name, 'w+') as stream: yaml.safe_dump(obj1, stream) obj2 = { 'clusters': [{ 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://other2-aztest-abc456-abcd4567.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster2' }], 'contexts': [{ 'context': { 'cluster': 'cluster2', 'user': '******' }, 'name': 'context2' }], 'users': [{ 'name': 'cluster2User_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token3' } }], 'current-context': 'some-context', } with open(addition.name, 'w+') as stream: yaml.safe_dump(obj2, stream) with self.assertRaises(CLIError): merge_kubernetes_configurations(existing.name, addition.name, False) merge_kubernetes_configurations(existing.name, addition.name, True) self.addCleanup(os.remove, addition.name) with open(existing.name, 'r') as stream: merged = yaml.safe_load(stream) self.addCleanup(os.remove, existing.name) self.assertEqual(len(merged['clusters']), 2) expected_clusters = [obj1['clusters'][0], obj2['clusters'][0]] self.assertEqual(merged['clusters'], expected_clusters) self.assertEqual(len(merged['contexts']), 2) expected_contexts = [obj1['contexts'][0], obj2['contexts'][0]] self.assertEqual(merged['contexts'], expected_contexts) self.assertEqual(len(merged['users']), 2) expected_users = [obj1['users'][0], obj2['users'][0]] self.assertEqual(merged['users'], expected_users) self.assertEqual(merged['current-context'], obj2['current-context'])
def test_merge_credentials_missing(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'clusters': None, 'contexts': [{ 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'context1' }], 'current-context': 'context1', 'kind': 'Config', 'preferences': {}, 'users': [{ 'name': 'user1', 'user': { 'client-certificate-data': 'clientcertificatedata1', 'client-key-data': 'clientkeydata1', 'token': 'token1' } }] } with open(existing.name, 'w+') as stream: yaml.safe_dump(obj1, stream) self.addCleanup(os.remove, existing.name) obj2 = { 'clusters': [{ 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster2' }], 'contexts': [{ 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'context2' }], 'current-context': 'context2', 'kind': 'Config', 'preferences': {}, 'users': None } with open(addition.name, 'w+') as stream: yaml.safe_dump(obj2, stream) self.addCleanup(os.remove, addition.name) merge_kubernetes_configurations(existing.name, addition.name, False) with open(existing.name, 'r') as stream: merged = yaml.safe_load(stream) self.assertEqual(len(merged['clusters']), 1) self.assertEqual(merged['clusters'], [obj2['clusters'][0]]) self.assertEqual(len(merged['contexts']), 2) self.assertEqual(merged['contexts'], [obj1['contexts'][0], obj2['contexts'][0]]) self.assertEqual(len(merged['users']), 1) self.assertEqual(merged['users'], [obj1['users'][0]]) self.assertEqual(merged['current-context'], obj2['current-context'])
def test_merge_admin_credentials(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'apiVersion': 'v1', 'clusters': [ { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'aztest' } ], 'contexts': [ { 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'aztest' } ], 'current-context': 'aztest', 'kind': 'Config', 'preferences': {}, 'users': [ { 'name': 'clusterUser_aztest_aztest', 'user': { 'client-certificate-data': 'clientcertificatedata1', 'client-key-data': 'clientkeydata1', 'token': 'token1' } } ] } with open(existing.name, 'w+') as stream: yaml.dump(obj1, stream) self.addCleanup(os.remove, existing.name) obj2 = { 'apiVersion': 'v1', 'clusters': [ { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata2', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'aztest' } ], 'contexts': [ { 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'aztest' } ], 'current-context': 'aztest', 'kind': 'Config', 'preferences': {}, 'users': [ { 'name': 'clusterAdmin_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token2' } } ] } with open(addition.name, 'w+') as stream: yaml.dump(obj2, stream) self.addCleanup(os.remove, addition.name) merge_kubernetes_configurations(existing.name, addition.name) with open(existing.name, 'r') as stream: merged = yaml.load(stream) self.assertEqual(len(merged['clusters']), 2) self.assertEqual([c['cluster'] for c in merged['clusters']], [{'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443'}, {'certificate-authority-data': 'certificateauthoritydata2', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443'}]) self.assertEqual(len(merged['contexts']), 2) self.assertEqual(merged['contexts'], [{'context': {'cluster': 'aztest', 'user': '******'}, 'name': 'aztest'}, {'context': {'cluster': 'aztest', 'user': '******'}, 'name': 'aztest-admin'}]) self.assertEqual(len(merged['users']), 2) self.assertEqual([u['name'] for u in merged['users']], ['clusterUser_aztest_aztest', 'clusterAdmin_aztest_aztest']) self.assertEqual(merged['current-context'], 'aztest-admin')
def test_merge_admin_credentials(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'apiVersion': 'v1', 'clusters': [ { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'aztest' } ], 'contexts': [ { 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'aztest' } ], 'current-context': 'aztest', 'kind': 'Config', 'preferences': {}, 'users': [ { 'name': 'clusterUser_aztest_aztest', 'user': { 'client-certificate-data': 'clientcertificatedata1', 'client-key-data': 'clientkeydata1', 'token': 'token1' } } ] } with open(existing.name, 'w+') as stream: yaml.dump(obj1, stream) self.addCleanup(os.remove, existing.name) obj2 = { 'apiVersion': 'v1', 'clusters': [ { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata2', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'aztest' } ], 'contexts': [ { 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'aztest' } ], 'current-context': 'aztest', 'kind': 'Config', 'preferences': {}, 'users': [ { 'name': 'clusterAdmin_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token2' } } ] } with open(addition.name, 'w+') as stream: yaml.dump(obj2, stream) self.addCleanup(os.remove, addition.name) merge_kubernetes_configurations(existing.name, addition.name) with open(existing.name, 'r') as stream: merged = yaml.load(stream) self.assertEqual(len(merged['clusters']), 2) self.assertEqual([c['cluster'] for c in merged['clusters']], [{'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443'}, {'certificate-authority-data': 'certificateauthoritydata2', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443'}]) self.assertEqual(len(merged['contexts']), 2) self.assertEqual(merged['contexts'], [{'context': {'cluster': 'aztest', 'user': '******'}, 'name': 'aztest'}, {'context': {'cluster': 'aztest', 'user': '******'}, 'name': 'aztest-admin'}]) self.assertEqual(len(merged['users']), 2) self.assertEqual([u['name'] for u in merged['users']], ['clusterUser_aztest_aztest', 'clusterAdmin_aztest_aztest']) self.assertEqual(merged['current-context'], 'aztest-admin')
def aksauth_connect(cmd, resource_group, cluster_name, tenant, username, password): subscription = get_subscription_id(cmd.cli_ctx) authority_url = ('https://login.microsoftonline.com/' + tenant) context = adal.AuthenticationContext( authority_url, api_version=1.0, ) LOGGER.info("Authenticating to AAD using ARM Resource and Default Client ID") #Create credentials object from our adal username and password flow. credentials = AdalAuthentication( context.acquire_token_with_username_password, 'https://management.azure.com/', username, password, '04b07795-8ddb-461a-bbee-02f9e1bf7b46' ) LOGGER.info("Getting Kubeconfig Skeleton") #Get the skeleton kubeconfig client = ContainerServiceClient(credentials, subscription) credentialResults = client.managed_clusters.list_cluster_user_credentials(resource_group, cluster_name) LOGGER.info("Write Kubeconfig Skeleton to temp file") #Write skeleton kubeconfig to temp file fd, temp_path = tempfile.mkstemp() additional_file = os.fdopen(fd, 'w+t') try: additional_file.write(credentialResults.kubeconfigs[0].value.decode(encoding='UTF-8')) additional_file.flush() finally: additional_file.close() LOGGER.info("Load Kubeconfig Skeleton to dict") #Open skeleton kubeconfig into a dict and extract server, client and context name with open(temp_path) as file: kconfig = yaml.load(file, Loader=yaml.FullLoader) apiServer = kconfig.get('users')[0].get('user').get('auth-provider').get('config').get('apiserver-id') clientId = kconfig.get('users')[0].get('user').get('auth-provider').get('config').get('client-id') contextName = kconfig.get('contexts')[0].get('name') os.remove(temp_path) LOGGER.info("Authenticate with client on behalf of user to API Server App") #Generate access token, refresh token, expiry details using client and server token = context.acquire_token_with_username_password( resource=apiServer, username=username, password=password, client_id=clientId) LOGGER.info("Subbing in User Identity details into Kubeconfig dict") #Sub in above into kubeconfig dict kconfig['users'][0]['user']['auth-provider']['config']['access-token']=token['accessToken'] kconfig['users'][0]['user']['auth-provider']['config']['refresh-token']=token['refreshToken'] kconfig['users'][0]['user']['auth-provider']['config']['expires-in']=str(token['expiresIn']) kconfig['users'][0]['user']['auth-provider']['config']['expires-on']=token['expiresOn'] LOGGER.info("Write Kubeconfig dict to temp file") #Write kubeconfig dict to temp file fd1, temp_path1 = tempfile.mkstemp() with open(temp_path1, 'w') as file: documents = yaml.dump(kconfig, file) #Get default kubeconfig location kconfigPath = str(Path.home()) + os.sep + '.kube' + os.sep + 'config' LOGGER.info("Check if ddefault Kubeconfig exists") #Create empty kubeconfig and path if it doesn't exist if os.path.exists(kconfigPath) != True: os.makedirs(os.path.dirname(kconfigPath), exist_ok=True) with open(kconfigPath, "w") as f: f.write("") LOGGER.info("merge_kubernetes_configurations temp kubeconfig with default kuebconfig") #Reuse Azure's method to merge our new kubeconfig with the existing one merge_kubernetes_configurations(kconfigPath, temp_path1, True, contextName)
def test_merge_credentials_already_present(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'clusters': [ { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://cluster1-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster1' }, { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://cluster2-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster2' } ], 'contexts': [ { 'context': { 'cluster': 'cluster1', 'user': '******' }, 'name': 'context1' }, { 'context': { 'cluster': 'cluster1', 'user': '******' }, 'name': 'context2' } ], 'users': [ { 'name': 'cluster1User_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token2' } }, { 'name': 'cluster2User_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token2' } } ], 'current-context': 'context1', } with open(existing.name, 'w+') as stream: yaml.dump(obj1, stream) obj2 = { 'clusters': [ { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://other2-aztest-abc456-abcd4567.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster2' } ], 'contexts': [ { 'context': { 'cluster': 'cluster2', 'user': '******' }, 'name': 'context2' } ], 'users': [ { 'name': 'cluster2User_aztest_aztest', 'user': { 'client-certificate-data': 'someclientcertificatedata2', 'client-key-data': 'someclientkeydata2', 'token': 'token3' } } ], 'current-context': 'some-context', } with open(addition.name, 'w+') as stream: yaml.dump(obj2, stream) with self.assertRaises(CLIError): merge_kubernetes_configurations(existing.name, addition.name, False) merge_kubernetes_configurations(existing.name, addition.name, True) self.addCleanup(os.remove, addition.name) with open(existing.name, 'r') as stream: merged = yaml.load(stream) self.addCleanup(os.remove, existing.name) self.assertEqual(len(merged['clusters']), 2) expected_clusters = [ obj1['clusters'][0], obj2['clusters'][0] ] self.assertEqual(merged['clusters'], expected_clusters) self.assertEqual(len(merged['contexts']), 2) expected_contexts = [ obj1['contexts'][0], obj2['contexts'][0] ] self.assertEqual(merged['contexts'], expected_contexts) self.assertEqual(len(merged['users']), 2) expected_users = [ obj1['users'][0], obj2['users'][0] ] self.assertEqual(merged['users'], expected_users) self.assertEqual(merged['current-context'], obj2['current-context'])
def test_merge_credentials_missing(self): existing = tempfile.NamedTemporaryFile(delete=False) existing.close() addition = tempfile.NamedTemporaryFile(delete=False) addition.close() obj1 = { 'clusters': None, 'contexts': [ { 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'context1' } ], 'current-context': 'context1', 'kind': 'Config', 'preferences': {}, 'users': [ { 'name': 'user1', 'user': { 'client-certificate-data': 'clientcertificatedata1', 'client-key-data': 'clientkeydata1', 'token': 'token1' } } ] } with open(existing.name, 'w+') as stream: yaml.safe_dump(obj1, stream) self.addCleanup(os.remove, existing.name) obj2 = { 'clusters': [ { 'cluster': { 'certificate-authority-data': 'certificateauthoritydata1', 'server': 'https://aztest-aztest-abc123-abcd1234.hcp.eastus.azmk8s.io:443' }, 'name': 'cluster2' } ], 'contexts': [ { 'context': { 'cluster': 'aztest', 'user': '******' }, 'name': 'context2' } ], 'current-context': 'context2', 'kind': 'Config', 'preferences': {}, 'users': None } with open(addition.name, 'w+') as stream: yaml.safe_dump(obj2, stream) self.addCleanup(os.remove, addition.name) merge_kubernetes_configurations(existing.name, addition.name, False) with open(existing.name, 'r') as stream: merged = yaml.safe_load(stream) self.assertEqual(len(merged['clusters']), 1) self.assertEqual(merged['clusters'], [obj2['clusters'][0]]) self.assertEqual(len(merged['contexts']), 2) self.assertEqual(merged['contexts'], [obj1['contexts'][0], obj2['contexts'][0]]) self.assertEqual(len(merged['users']), 1) self.assertEqual(merged['users'], [obj1['users'][0]]) self.assertEqual(merged['current-context'], obj2['current-context'])