skypilot-nightly 1.0.0.dev20240909__py3-none-any.whl → 1.0.0.dev20240911__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. sky/__init__.py +2 -2
  2. sky/adaptors/kubernetes.py +33 -67
  3. sky/authentication.py +12 -7
  4. sky/backends/backend_utils.py +40 -33
  5. sky/backends/cloud_vm_ray_backend.py +1 -1
  6. sky/check.py +1 -1
  7. sky/clouds/aws.py +8 -6
  8. sky/clouds/azure.py +7 -5
  9. sky/clouds/cloud.py +43 -14
  10. sky/clouds/cudo.py +1 -1
  11. sky/clouds/fluidstack.py +2 -2
  12. sky/clouds/gcp.py +12 -7
  13. sky/clouds/kubernetes.py +28 -15
  14. sky/clouds/lambda_cloud.py +2 -2
  15. sky/clouds/oci.py +1 -1
  16. sky/clouds/paperspace.py +1 -1
  17. sky/clouds/runpod.py +1 -1
  18. sky/clouds/scp.py +2 -2
  19. sky/clouds/service_catalog/aws_catalog.py +1 -1
  20. sky/clouds/vsphere.py +1 -1
  21. sky/provision/kubernetes/config.py +52 -34
  22. sky/provision/kubernetes/instance.py +73 -61
  23. sky/provision/kubernetes/network.py +11 -5
  24. sky/provision/kubernetes/network_utils.py +10 -8
  25. sky/provision/kubernetes/utils.py +72 -45
  26. sky/skylet/log_lib.py +4 -1
  27. sky/skylet/subprocess_daemon.py +47 -15
  28. sky/templates/kubernetes-port-forward-proxy-command.sh +29 -4
  29. sky/templates/kubernetes-ray.yml.j2 +5 -0
  30. sky/templates/lambda-ray.yml.j2 +2 -2
  31. sky/utils/command_runner.py +12 -6
  32. sky/utils/command_runner.pyi +1 -1
  33. sky/utils/kubernetes/rsync_helper.sh +12 -3
  34. {skypilot_nightly-1.0.0.dev20240909.dist-info → skypilot_nightly-1.0.0.dev20240911.dist-info}/METADATA +1 -1
  35. {skypilot_nightly-1.0.0.dev20240909.dist-info → skypilot_nightly-1.0.0.dev20240911.dist-info}/RECORD +39 -39
  36. {skypilot_nightly-1.0.0.dev20240909.dist-info → skypilot_nightly-1.0.0.dev20240911.dist-info}/LICENSE +0 -0
  37. {skypilot_nightly-1.0.0.dev20240909.dist-info → skypilot_nightly-1.0.0.dev20240911.dist-info}/WHEEL +0 -0
  38. {skypilot_nightly-1.0.0.dev20240909.dist-info → skypilot_nightly-1.0.0.dev20240911.dist-info}/entry_points.txt +0 -0
  39. {skypilot_nightly-1.0.0.dev20240909.dist-info → skypilot_nightly-1.0.0.dev20240911.dist-info}/top_level.txt +0 -0
sky/clouds/kubernetes.py CHANGED
@@ -145,11 +145,6 @@ class Kubernetes(clouds.Cloud):
145
145
  def __repr__(self):
146
146
  return self._REPR
147
147
 
148
- @classmethod
149
- def get_port(cls, svc_name) -> int:
150
- ns = kubernetes_utils.get_current_kube_config_context_namespace()
151
- return kubernetes_utils.get_port(svc_name, ns)
152
-
153
148
  @classmethod
154
149
  def get_default_instance_type(
155
150
  cls,
@@ -338,6 +333,12 @@ class Kubernetes(clouds.Cloud):
338
333
  'image_id': image_id,
339
334
  }
340
335
 
336
+ # Add kubecontext if it is set. It may be None if SkyPilot is running
337
+ # inside a pod with in-cluster auth.
338
+ curr_context = kubernetes_utils.get_current_kube_config_context_name()
339
+ if curr_context is not None:
340
+ deploy_vars['k8s_context'] = curr_context
341
+
341
342
  return deploy_vars
342
343
 
343
344
  def _get_feasible_launchable_resources(
@@ -441,21 +442,33 @@ class Kubernetes(clouds.Cloud):
441
442
  ' Cluster used is determined by the kubeconfig.')
442
443
  return region, zone
443
444
 
445
+ @staticmethod
446
+ def get_identity_from_context(context):
447
+ if 'namespace' in context['context']:
448
+ namespace = context['context']['namespace']
449
+ else:
450
+ namespace = kubernetes_utils.DEFAULT_NAMESPACE
451
+ user = context['context']['user']
452
+ cluster = context['context']['cluster']
453
+ identity_str = f'{cluster}_{user}_{namespace}'
454
+ return identity_str
455
+
444
456
  @classmethod
445
- def get_current_user_identity(cls) -> Optional[List[str]]:
457
+ def get_user_identities(cls) -> Optional[List[List[str]]]:
446
458
  k8s = kubernetes.kubernetes
459
+ identities = []
447
460
  try:
448
- _, current_context = k8s.config.list_kube_config_contexts()
449
- if 'namespace' in current_context['context']:
450
- namespace = current_context['context']['namespace']
451
- else:
452
- namespace = kubernetes_utils.DEFAULT_NAMESPACE
453
-
454
- user = current_context['context']['user']
455
- cluster = current_context['context']['cluster']
456
- return [f'{cluster}_{user}_{namespace}']
461
+ all_contexts, current_context = (
462
+ k8s.config.list_kube_config_contexts())
457
463
  except k8s.config.config_exception.ConfigException:
458
464
  return None
465
+ # Add current context at the head of the list
466
+ current_identity = [cls.get_identity_from_context(current_context)]
467
+ identities.append(current_identity)
468
+ for context in all_contexts:
469
+ identity = [cls.get_identity_from_context(context)]
470
+ identities.append(identity)
471
+ return identities
459
472
 
460
473
  @classmethod
461
474
  def is_label_valid(cls, label_key: str,
@@ -258,8 +258,8 @@ class Lambda(clouds.Cloud):
258
258
  }
259
259
 
260
260
  @classmethod
261
- def get_current_user_identity(cls) -> Optional[List[str]]:
262
- # TODO(ewzeng): Implement get_current_user_identity for Lambda
261
+ def get_user_identities(cls) -> Optional[List[List[str]]]:
262
+ # TODO(ewzeng): Implement get_user_identities for Lambda
263
263
  return None
264
264
 
265
265
  def instance_type_exists(self, instance_type: str) -> bool:
sky/clouds/oci.py CHANGED
@@ -455,7 +455,7 @@ class OCI(clouds.Cloud):
455
455
  return file_mounts
456
456
 
457
457
  @classmethod
458
- def get_current_user_identity(cls) -> Optional[List[str]]:
458
+ def get_user_identities(cls) -> Optional[List[List[str]]]:
459
459
  # NOTE: used for very advanced SkyPilot functionality
460
460
  # Can implement later if desired
461
461
  # If the user switches the compartment_ocid, the existing clusters
sky/clouds/paperspace.py CHANGED
@@ -280,7 +280,7 @@ class Paperspace(clouds.Cloud):
280
280
  }
281
281
 
282
282
  @classmethod
283
- def get_current_user_identity(cls) -> Optional[List[str]]:
283
+ def get_user_identities(cls) -> Optional[List[List[str]]]:
284
284
  # NOTE: used for very advanced SkyPilot functionality
285
285
  # Can implement later if desired
286
286
  return None
sky/clouds/runpod.py CHANGED
@@ -268,7 +268,7 @@ class RunPod(clouds.Cloud):
268
268
  }
269
269
 
270
270
  @classmethod
271
- def get_current_user_identity(cls) -> Optional[List[str]]:
271
+ def get_user_identities(cls) -> Optional[List[List[str]]]:
272
272
  # NOTE: used for very advanced SkyPilot functionality
273
273
  # Can implement later if desired
274
274
  return None
sky/clouds/scp.py CHANGED
@@ -337,8 +337,8 @@ class SCP(clouds.Cloud):
337
337
  }
338
338
 
339
339
  @classmethod
340
- def get_current_user_identity(cls) -> Optional[List[str]]:
341
- # TODO(jgoo1): Implement get_current_user_identity for SCP
340
+ def get_user_identities(cls) -> Optional[List[List[str]]]:
341
+ # TODO(jgoo1): Implement get_user_identities for SCP
342
342
  return None
343
343
 
344
344
  def instance_type_exists(self, instance_type: str) -> bool:
@@ -123,7 +123,7 @@ def _fetch_and_apply_az_mapping(df: common.LazyDataFrame) -> 'pd.DataFrame':
123
123
  with the zone name (e.g. us-east-1a).
124
124
  """
125
125
  try:
126
- user_identity_list = aws.AWS.get_current_user_identity()
126
+ user_identity_list = aws.AWS.get_active_user_identity()
127
127
  assert user_identity_list, user_identity_list
128
128
  user_identity = user_identity_list[0]
129
129
  aws_user_hash = hashlib.md5(user_identity.encode()).hexdigest()[:8]
sky/clouds/vsphere.py CHANGED
@@ -308,7 +308,7 @@ class Vsphere(clouds.Cloud):
308
308
  }
309
309
 
310
310
  @classmethod
311
- def get_current_user_identity(cls) -> Optional[List[str]]:
311
+ def get_user_identities(cls) -> Optional[List[List[str]]]:
312
312
  # NOTE: used for very advanced SkyPilot functionality
313
313
  # Can implement later if desired
314
314
  return None
@@ -23,14 +23,16 @@ def bootstrap_instances(
23
23
  region: str, cluster_name: str,
24
24
  config: common.ProvisionConfig) -> common.ProvisionConfig:
25
25
  del region, cluster_name # unused
26
- namespace = kubernetes_utils.get_current_kube_config_context_namespace()
26
+ namespace = kubernetes_utils.get_namespace_from_config(
27
+ config.provider_config)
28
+ context = kubernetes_utils.get_context_from_config(config.provider_config)
27
29
 
28
- _configure_services(namespace, config.provider_config)
30
+ _configure_services(namespace, context, config.provider_config)
29
31
 
30
32
  networking_mode = network_utils.get_networking_mode(
31
33
  config.provider_config.get('networking_mode'))
32
34
  if networking_mode == kubernetes_enums.KubernetesNetworkingMode.NODEPORT:
33
- config = _configure_ssh_jump(namespace, config)
35
+ config = _configure_ssh_jump(namespace, context, config)
34
36
 
35
37
  requested_service_account = config.node_config['spec']['serviceAccountName']
36
38
  if (requested_service_account ==
@@ -40,16 +42,20 @@ def bootstrap_instances(
40
42
  # necessary roles and role bindings.
41
43
  # If not, set up the roles and bindings for skypilot-service-account
42
44
  # here.
43
- _configure_autoscaler_service_account(namespace, config.provider_config)
45
+ _configure_autoscaler_service_account(namespace, context,
46
+ config.provider_config)
44
47
  _configure_autoscaler_role(namespace,
48
+ context,
45
49
  config.provider_config,
46
50
  role_field='autoscaler_role')
47
51
  _configure_autoscaler_role_binding(
48
52
  namespace,
53
+ context,
49
54
  config.provider_config,
50
55
  binding_field='autoscaler_role_binding')
51
- _configure_autoscaler_cluster_role(namespace, config.provider_config)
52
- _configure_autoscaler_cluster_role_binding(namespace,
56
+ _configure_autoscaler_cluster_role(namespace, context,
57
+ config.provider_config)
58
+ _configure_autoscaler_cluster_role_binding(namespace, context,
53
59
  config.provider_config)
54
60
  # SkyPilot system namespace is required for FUSE mounting. Here we just
55
61
  # create the namespace and set up the necessary permissions.
@@ -71,10 +77,12 @@ def bootstrap_instances(
71
77
  'and role binding.')
72
78
  try:
73
79
  _configure_autoscaler_role(namespace,
80
+ context,
74
81
  config.provider_config,
75
82
  role_field='autoscaler_ingress_role')
76
83
  _configure_autoscaler_role_binding(
77
84
  namespace,
85
+ context,
78
86
  config.provider_config,
79
87
  binding_field='autoscaler_ingress_role_binding')
80
88
  except kubernetes.api_exception() as e:
@@ -239,7 +247,7 @@ def _get_resource(container_resources: Dict[str, Any], resource_name: str,
239
247
 
240
248
 
241
249
  def _configure_autoscaler_service_account(
242
- namespace: str, provider_config: Dict[str, Any]) -> None:
250
+ namespace: str, context: str, provider_config: Dict[str, Any]) -> None:
243
251
  account_field = 'autoscaler_service_account'
244
252
  if account_field not in provider_config:
245
253
  logger.info('_configure_autoscaler_service_account: '
@@ -254,7 +262,7 @@ def _configure_autoscaler_service_account(
254
262
 
255
263
  name = account['metadata']['name']
256
264
  field_selector = f'metadata.name={name}'
257
- accounts = (kubernetes.core_api().list_namespaced_service_account(
265
+ accounts = (kubernetes.core_api(context).list_namespaced_service_account(
258
266
  namespace, field_selector=field_selector).items)
259
267
  if len(accounts) > 0:
260
268
  assert len(accounts) == 1
@@ -267,12 +275,14 @@ def _configure_autoscaler_service_account(
267
275
 
268
276
  logger.info('_configure_autoscaler_service_account: '
269
277
  f'{not_found_msg(account_field, name)}')
270
- kubernetes.core_api().create_namespaced_service_account(namespace, account)
278
+ kubernetes.core_api(context).create_namespaced_service_account(
279
+ namespace, account)
271
280
  logger.info('_configure_autoscaler_service_account: '
272
281
  f'{created_msg(account_field, name)}')
273
282
 
274
283
 
275
- def _configure_autoscaler_role(namespace: str, provider_config: Dict[str, Any],
284
+ def _configure_autoscaler_role(namespace: str, context: str,
285
+ provider_config: Dict[str, Any],
276
286
  role_field: str) -> None:
277
287
  """ Reads the role from the provider config, creates if it does not exist.
278
288
 
@@ -295,7 +305,7 @@ def _configure_autoscaler_role(namespace: str, provider_config: Dict[str, Any],
295
305
 
296
306
  name = role['metadata']['name']
297
307
  field_selector = f'metadata.name={name}'
298
- roles = (kubernetes.auth_api().list_namespaced_role(
308
+ roles = (kubernetes.auth_api(context).list_namespaced_role(
299
309
  namespace, field_selector=field_selector).items)
300
310
  if len(roles) > 0:
301
311
  assert len(roles) == 1
@@ -308,17 +318,19 @@ def _configure_autoscaler_role(namespace: str, provider_config: Dict[str, Any],
308
318
  return
309
319
  logger.info('_configure_autoscaler_role: '
310
320
  f'{updating_existing_msg(role_field, name)}')
311
- kubernetes.auth_api().patch_namespaced_role(name, namespace, role)
321
+ kubernetes.auth_api(context).patch_namespaced_role(
322
+ name, namespace, role)
312
323
  return
313
324
 
314
325
  logger.info('_configure_autoscaler_role: '
315
326
  f'{not_found_msg(role_field, name)}')
316
- kubernetes.auth_api().create_namespaced_role(namespace, role)
327
+ kubernetes.auth_api(context).create_namespaced_role(namespace, role)
317
328
  logger.info(f'_configure_autoscaler_role: {created_msg(role_field, name)}')
318
329
 
319
330
 
320
331
  def _configure_autoscaler_role_binding(
321
332
  namespace: str,
333
+ context: str,
322
334
  provider_config: Dict[str, Any],
323
335
  binding_field: str,
324
336
  override_name: Optional[str] = None,
@@ -359,7 +371,7 @@ def _configure_autoscaler_role_binding(
359
371
  name = binding['metadata']['name']
360
372
 
361
373
  field_selector = f'metadata.name={name}'
362
- role_bindings = (kubernetes.auth_api().list_namespaced_role_binding(
374
+ role_bindings = (kubernetes.auth_api(context).list_namespaced_role_binding(
363
375
  rb_namespace, field_selector=field_selector).items)
364
376
  if len(role_bindings) > 0:
365
377
  assert len(role_bindings) == 1
@@ -372,18 +384,19 @@ def _configure_autoscaler_role_binding(
372
384
  return
373
385
  logger.info('_configure_autoscaler_role_binding: '
374
386
  f'{updating_existing_msg(binding_field, name)}')
375
- kubernetes.auth_api().patch_namespaced_role_binding(
387
+ kubernetes.auth_api(context).patch_namespaced_role_binding(
376
388
  name, rb_namespace, binding)
377
389
  return
378
390
 
379
391
  logger.info('_configure_autoscaler_role_binding: '
380
392
  f'{not_found_msg(binding_field, name)}')
381
- kubernetes.auth_api().create_namespaced_role_binding(rb_namespace, binding)
393
+ kubernetes.auth_api(context).create_namespaced_role_binding(
394
+ rb_namespace, binding)
382
395
  logger.info('_configure_autoscaler_role_binding: '
383
396
  f'{created_msg(binding_field, name)}')
384
397
 
385
398
 
386
- def _configure_autoscaler_cluster_role(namespace,
399
+ def _configure_autoscaler_cluster_role(namespace, context,
387
400
  provider_config: Dict[str, Any]) -> None:
388
401
  role_field = 'autoscaler_cluster_role'
389
402
  if role_field not in provider_config:
@@ -399,7 +412,7 @@ def _configure_autoscaler_cluster_role(namespace,
399
412
 
400
413
  name = role['metadata']['name']
401
414
  field_selector = f'metadata.name={name}'
402
- cluster_roles = (kubernetes.auth_api().list_cluster_role(
415
+ cluster_roles = (kubernetes.auth_api(context).list_cluster_role(
403
416
  field_selector=field_selector).items)
404
417
  if len(cluster_roles) > 0:
405
418
  assert len(cluster_roles) == 1
@@ -411,18 +424,18 @@ def _configure_autoscaler_cluster_role(namespace,
411
424
  return
412
425
  logger.info('_configure_autoscaler_cluster_role: '
413
426
  f'{updating_existing_msg(role_field, name)}')
414
- kubernetes.auth_api().patch_cluster_role(name, role)
427
+ kubernetes.auth_api(context).patch_cluster_role(name, role)
415
428
  return
416
429
 
417
430
  logger.info('_configure_autoscaler_cluster_role: '
418
431
  f'{not_found_msg(role_field, name)}')
419
- kubernetes.auth_api().create_cluster_role(role)
432
+ kubernetes.auth_api(context).create_cluster_role(role)
420
433
  logger.info(
421
434
  f'_configure_autoscaler_cluster_role: {created_msg(role_field, name)}')
422
435
 
423
436
 
424
437
  def _configure_autoscaler_cluster_role_binding(
425
- namespace, provider_config: Dict[str, Any]) -> None:
438
+ namespace, context, provider_config: Dict[str, Any]) -> None:
426
439
  binding_field = 'autoscaler_cluster_role_binding'
427
440
  if binding_field not in provider_config:
428
441
  logger.info('_configure_autoscaler_cluster_role_binding: '
@@ -444,7 +457,7 @@ def _configure_autoscaler_cluster_role_binding(
444
457
 
445
458
  name = binding['metadata']['name']
446
459
  field_selector = f'metadata.name={name}'
447
- cr_bindings = (kubernetes.auth_api().list_cluster_role_binding(
460
+ cr_bindings = (kubernetes.auth_api(context).list_cluster_role_binding(
448
461
  field_selector=field_selector).items)
449
462
  if len(cr_bindings) > 0:
450
463
  assert len(cr_bindings) == 1
@@ -458,17 +471,17 @@ def _configure_autoscaler_cluster_role_binding(
458
471
  return
459
472
  logger.info('_configure_autoscaler_cluster_role_binding: '
460
473
  f'{updating_existing_msg(binding_field, name)}')
461
- kubernetes.auth_api().patch_cluster_role_binding(name, binding)
474
+ kubernetes.auth_api(context).patch_cluster_role_binding(name, binding)
462
475
  return
463
476
 
464
477
  logger.info('_configure_autoscaler_cluster_role_binding: '
465
478
  f'{not_found_msg(binding_field, name)}')
466
- kubernetes.auth_api().create_cluster_role_binding(binding)
479
+ kubernetes.auth_api(context).create_cluster_role_binding(binding)
467
480
  logger.info('_configure_autoscaler_cluster_role_binding: '
468
481
  f'{created_msg(binding_field, name)}')
469
482
 
470
483
 
471
- def _configure_ssh_jump(namespace, config: common.ProvisionConfig):
484
+ def _configure_ssh_jump(namespace, context, config: common.ProvisionConfig):
472
485
  """Creates a SSH jump pod to connect to the cluster.
473
486
 
474
487
  Also updates config['auth']['ssh_proxy_command'] to use the newly created
@@ -499,7 +512,7 @@ def _configure_ssh_jump(namespace, config: common.ProvisionConfig):
499
512
  # service is missing, we should raise an error.
500
513
 
501
514
  kubernetes_utils.setup_ssh_jump_pod(ssh_jump_name, ssh_jump_image,
502
- ssh_key_secret_name, namespace)
515
+ ssh_key_secret_name, namespace, context)
503
516
  return config
504
517
 
505
518
 
@@ -512,12 +525,14 @@ def _configure_skypilot_system_namespace(
512
525
  """
513
526
  svc_account_namespace = provider_config['namespace']
514
527
  skypilot_system_namespace = provider_config['skypilot_system_namespace']
515
- kubernetes_utils.create_namespace(skypilot_system_namespace)
528
+ context = kubernetes_utils.get_context_from_config(provider_config)
529
+ kubernetes_utils.create_namespace(skypilot_system_namespace, context)
516
530
 
517
531
  # Note - this must be run only after the service account has been
518
532
  # created in the cluster (in bootstrap_instances).
519
533
  # Create the role in the skypilot-system namespace if it does not exist.
520
534
  _configure_autoscaler_role(skypilot_system_namespace,
535
+ context,
521
536
  provider_config,
522
537
  role_field='autoscaler_skypilot_system_role')
523
538
  # We must create a unique role binding per-namespace that SkyPilot is
@@ -532,6 +547,7 @@ def _configure_skypilot_system_namespace(
532
547
  # account is created in.
533
548
  _configure_autoscaler_role_binding(
534
549
  skypilot_system_namespace,
550
+ context,
535
551
  provider_config,
536
552
  binding_field='autoscaler_skypilot_system_role_binding',
537
553
  override_name=override_name,
@@ -555,6 +571,7 @@ def _configure_fuse_mounting(provider_config: Dict[str, Any]) -> None:
555
571
  logger.info('_configure_fuse_mounting: Setting up FUSE device manager.')
556
572
 
557
573
  fuse_device_manager_namespace = provider_config['skypilot_system_namespace']
574
+ context = kubernetes_utils.get_context_from_config(provider_config)
558
575
 
559
576
  # Read the device manager YAMLs from the manifests directory
560
577
  root_dir = os.path.dirname(os.path.dirname(__file__))
@@ -567,7 +584,7 @@ def _configure_fuse_mounting(provider_config: Dict[str, Any]) -> None:
567
584
  config_map = yaml.safe_load(file)
568
585
  kubernetes_utils.merge_custom_metadata(config_map['metadata'])
569
586
  try:
570
- kubernetes.core_api().create_namespaced_config_map(
587
+ kubernetes.core_api(context).create_namespaced_config_map(
571
588
  fuse_device_manager_namespace, config_map)
572
589
  except kubernetes.api_exception() as e:
573
590
  if e.status == 409:
@@ -587,7 +604,7 @@ def _configure_fuse_mounting(provider_config: Dict[str, Any]) -> None:
587
604
  daemonset = yaml.safe_load(file)
588
605
  kubernetes_utils.merge_custom_metadata(daemonset['metadata'])
589
606
  try:
590
- kubernetes.apps_api().create_namespaced_daemon_set(
607
+ kubernetes.apps_api(context).create_namespaced_daemon_set(
591
608
  fuse_device_manager_namespace, daemonset)
592
609
  except kubernetes.api_exception() as e:
593
610
  if e.status == 409:
@@ -603,8 +620,8 @@ def _configure_fuse_mounting(provider_config: Dict[str, Any]) -> None:
603
620
  f'in namespace {fuse_device_manager_namespace!r}')
604
621
 
605
622
 
606
- def _configure_services(namespace: str, provider_config: Dict[str,
607
- Any]) -> None:
623
+ def _configure_services(namespace: str, context: str,
624
+ provider_config: Dict[str, Any]) -> None:
608
625
  service_field = 'services'
609
626
  if service_field not in provider_config:
610
627
  logger.info(f'_configure_services: {not_provided_msg(service_field)}')
@@ -619,7 +636,7 @@ def _configure_services(namespace: str, provider_config: Dict[str,
619
636
 
620
637
  name = service['metadata']['name']
621
638
  field_selector = f'metadata.name={name}'
622
- services = (kubernetes.core_api().list_namespaced_service(
639
+ services = (kubernetes.core_api(context).list_namespaced_service(
623
640
  namespace, field_selector=field_selector).items)
624
641
  if len(services) > 0:
625
642
  assert len(services) == 1
@@ -633,12 +650,13 @@ def _configure_services(namespace: str, provider_config: Dict[str,
633
650
  else:
634
651
  logger.info('_configure_services: '
635
652
  f'{updating_existing_msg("service", name)}')
636
- kubernetes.core_api().patch_namespaced_service(
653
+ kubernetes.core_api(context).patch_namespaced_service(
637
654
  name, namespace, service)
638
655
  else:
639
656
  logger.info(
640
657
  f'_configure_services: {not_found_msg("service", name)}')
641
- kubernetes.core_api().create_namespaced_service(namespace, service)
658
+ kubernetes.core_api(context).create_namespaced_service(
659
+ namespace, service)
642
660
  logger.info(f'_configure_services: {created_msg("service", name)}')
643
661
 
644
662