github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/caas/kubernetes/provider/connection.go (about)

     1  // Copyright 2021 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provider
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"github.com/juju/errors"
    11  	"k8s.io/apimachinery/pkg/labels"
    12  
    13  	k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants"
    14  	k8sproxy "github.com/juju/juju/caas/kubernetes/provider/proxy"
    15  	"github.com/juju/juju/proxy"
    16  )
    17  
    18  // ProxyToApplication attempts to construct a Juju proxier for use in proxying
    19  // connections to the specified application. This assume the presence of a
    20  // corresponding service for the application.
    21  func (k *kubernetesClient) ProxyToApplication(appName, remotePort string) (proxy.Proxier, error) {
    22  	svc, err := findServiceForApplication(
    23  		context.TODO(),
    24  		k.client().CoreV1().Services(k.namespace),
    25  		appName,
    26  		k.IsLegacyLabels())
    27  	if err != nil {
    28  		return nil, errors.Annotatef(err, "finding service to proxy to for application %s", appName)
    29  	}
    30  
    31  	proxyName := fmt.Sprintf("%s-model-proxy", k.CurrentModel())
    32  	err = k8sproxy.EnsureProxyService(
    33  		context.Background(),
    34  		labels.Set{},
    35  		proxyName,
    36  		k.clock,
    37  		k.client().RbacV1().Roles(k.GetCurrentNamespace()),
    38  		k.client().RbacV1().RoleBindings(k.GetCurrentNamespace()),
    39  		k.client().CoreV1().ServiceAccounts(k.GetCurrentNamespace()),
    40  		k.client().CoreV1().Secrets(k.GetCurrentNamespace()),
    41  	)
    42  	if err != nil {
    43  		return nil, errors.Annotatef(err, "ensuring proxy service for application %s", appName)
    44  	}
    45  
    46  	err = k8sproxy.WaitForProxyService(
    47  		context.Background(),
    48  		proxyName,
    49  		k.client().CoreV1().ServiceAccounts(k.GetCurrentNamespace()),
    50  	)
    51  	if err != nil {
    52  		return nil, errors.Annotatef(err, "waiting for proxy service for application %s", appName)
    53  	}
    54  
    55  	config := k8sproxy.GetProxyConfig{
    56  		APIHost:    k.k8sCfgUnlocked.Host,
    57  		Namespace:  k.GetCurrentNamespace(),
    58  		RemotePort: remotePort,
    59  		Service:    svc.Name,
    60  	}
    61  
    62  	return k8sproxy.GetProxy(
    63  		proxyName,
    64  		config,
    65  		k.client().CoreV1().ServiceAccounts(k.GetCurrentNamespace()),
    66  		k.client().CoreV1().Secrets(k.GetCurrentNamespace()),
    67  	)
    68  }
    69  
    70  // ConnectionProxyInfo provides the means for getting a proxier onto a Juju
    71  // controller deployed in this provider.
    72  func (k *kubernetesClient) ConnectionProxyInfo() (proxy.Proxier, error) {
    73  	p, err := k8sproxy.GetControllerProxy(
    74  		getBootstrapResourceName(k8sconstants.JujuControllerStackName, proxyResourceName),
    75  		k.k8sCfgUnlocked.Host,
    76  		k.client().CoreV1().ConfigMaps(k.GetCurrentNamespace()),
    77  		k.client().CoreV1().ServiceAccounts(k.GetCurrentNamespace()),
    78  		k.client().CoreV1().Secrets(k.GetCurrentNamespace()),
    79  	)
    80  
    81  	// If an error occurred return a nil to avoid converting the nil
    82  	// *Proxier into a typed nil which allows MarshalYAML to be called
    83  	// against a nil value which effectively causes a nil pointer
    84  	// dereference.
    85  	if err != nil {
    86  		return nil, errors.Trace(err)
    87  	}
    88  	return p, nil
    89  }