mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-17 02:58:41 +00:00
cmd/k8s-operator: Set login server on tsrecorder nodes (#16443)
This commit modifies the recorder node reconciler to include the environment variable added in https://github.com/tailscale/corp/pull/30058 which allows for configuration of the coordination server. Updates https://github.com/tailscale/corp/issues/29847 Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit is contained in:
parent
3a4b439c62
commit
5dc11d50f7
@ -82,6 +82,7 @@ func main() {
|
||||
tsFirewallMode = defaultEnv("PROXY_FIREWALL_MODE", "")
|
||||
defaultProxyClass = defaultEnv("PROXY_DEFAULT_CLASS", "")
|
||||
isDefaultLoadBalancer = defaultBool("OPERATOR_DEFAULT_LOAD_BALANCER", false)
|
||||
loginServer = strings.TrimSuffix(defaultEnv("OPERATOR_LOGIN_SERVER", ""), "/")
|
||||
)
|
||||
|
||||
var opts []kzap.Opts
|
||||
@ -115,7 +116,7 @@ func main() {
|
||||
hostinfo.SetApp(kubetypes.AppAPIServerProxy)
|
||||
}
|
||||
|
||||
s, tsc := initTSNet(zlog)
|
||||
s, tsc := initTSNet(zlog, loginServer)
|
||||
defer s.Close()
|
||||
restConfig := config.GetConfigOrDie()
|
||||
apiproxy.MaybeLaunchAPIServerProxy(zlog, restConfig, s, mode)
|
||||
@ -131,6 +132,7 @@ func main() {
|
||||
proxyTags: tags,
|
||||
proxyFirewallMode: tsFirewallMode,
|
||||
defaultProxyClass: defaultProxyClass,
|
||||
loginServer: loginServer,
|
||||
}
|
||||
runReconcilers(rOpts)
|
||||
}
|
||||
@ -138,14 +140,13 @@ func main() {
|
||||
// initTSNet initializes the tsnet.Server and logs in to Tailscale. It uses the
|
||||
// CLIENT_ID_FILE and CLIENT_SECRET_FILE environment variables to authenticate
|
||||
// with Tailscale.
|
||||
func initTSNet(zlog *zap.SugaredLogger) (*tsnet.Server, tsClient) {
|
||||
func initTSNet(zlog *zap.SugaredLogger, loginServer string) (*tsnet.Server, tsClient) {
|
||||
var (
|
||||
clientIDPath = defaultEnv("CLIENT_ID_FILE", "")
|
||||
clientSecretPath = defaultEnv("CLIENT_SECRET_FILE", "")
|
||||
hostname = defaultEnv("OPERATOR_HOSTNAME", "tailscale-operator")
|
||||
kubeSecret = defaultEnv("OPERATOR_SECRET", "")
|
||||
operatorTags = defaultEnv("OPERATOR_INITIAL_TAGS", "tag:k8s-operator")
|
||||
loginServer = strings.TrimSuffix(defaultEnv("OPERATOR_LOGIN_SERVER", ""), "/")
|
||||
)
|
||||
startlog := zlog.Named("startup")
|
||||
if clientIDPath == "" || clientSecretPath == "" {
|
||||
@ -610,6 +611,7 @@ func runReconcilers(opts reconcilerOpts) {
|
||||
l: opts.log.Named("recorder-reconciler"),
|
||||
clock: tstime.DefaultClock{},
|
||||
tsClient: opts.tsClient,
|
||||
loginServer: opts.loginServer,
|
||||
})
|
||||
if err != nil {
|
||||
startlog.Fatalf("could not create Recorder reconciler: %v", err)
|
||||
@ -693,6 +695,8 @@ type reconcilerOpts struct {
|
||||
// class for proxies that do not have a ProxyClass set.
|
||||
// this is defined by an operator env variable.
|
||||
defaultProxyClass string
|
||||
// loginServer is the coordination server URL that should be used by managed resources.
|
||||
loginServer string
|
||||
}
|
||||
|
||||
// enqueueAllIngressEgressProxySvcsinNS returns a reconcile request for each
|
||||
|
@ -59,6 +59,7 @@ type RecorderReconciler struct {
|
||||
clock tstime.Clock
|
||||
tsNamespace string
|
||||
tsClient tsClient
|
||||
loginServer string
|
||||
|
||||
mu sync.Mutex // protects following
|
||||
recorders set.Slice[types.UID] // for recorders gauge
|
||||
@ -202,7 +203,7 @@ func (r *RecorderReconciler) maybeProvision(ctx context.Context, tsr *tsapi.Reco
|
||||
}); err != nil {
|
||||
return fmt.Errorf("error creating RoleBinding: %w", err)
|
||||
}
|
||||
ss := tsrStatefulSet(tsr, r.tsNamespace)
|
||||
ss := tsrStatefulSet(tsr, r.tsNamespace, r.loginServer)
|
||||
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, ss, func(s *appsv1.StatefulSet) {
|
||||
s.ObjectMeta.Labels = ss.ObjectMeta.Labels
|
||||
s.ObjectMeta.Annotations = ss.ObjectMeta.Annotations
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
"tailscale.com/version"
|
||||
)
|
||||
|
||||
func tsrStatefulSet(tsr *tsapi.Recorder, namespace string) *appsv1.StatefulSet {
|
||||
func tsrStatefulSet(tsr *tsapi.Recorder, namespace string, loginServer string) *appsv1.StatefulSet {
|
||||
return &appsv1.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: tsr.Name,
|
||||
@ -59,7 +59,7 @@ func tsrStatefulSet(tsr *tsapi.Recorder, namespace string) *appsv1.StatefulSet {
|
||||
ImagePullPolicy: tsr.Spec.StatefulSet.Pod.Container.ImagePullPolicy,
|
||||
Resources: tsr.Spec.StatefulSet.Pod.Container.Resources,
|
||||
SecurityContext: tsr.Spec.StatefulSet.Pod.Container.SecurityContext,
|
||||
Env: env(tsr),
|
||||
Env: env(tsr, loginServer),
|
||||
EnvFrom: func() []corev1.EnvFromSource {
|
||||
if tsr.Spec.Storage.S3 == nil || tsr.Spec.Storage.S3.Credentials.Secret.Name == "" {
|
||||
return nil
|
||||
@ -201,7 +201,7 @@ func tsrStateSecret(tsr *tsapi.Recorder, namespace string) *corev1.Secret {
|
||||
}
|
||||
}
|
||||
|
||||
func env(tsr *tsapi.Recorder) []corev1.EnvVar {
|
||||
func env(tsr *tsapi.Recorder, loginServer string) []corev1.EnvVar {
|
||||
envs := []corev1.EnvVar{
|
||||
{
|
||||
Name: "TS_AUTHKEY",
|
||||
@ -239,6 +239,10 @@ func env(tsr *tsapi.Recorder) []corev1.EnvVar {
|
||||
Name: "TSRECORDER_HOSTNAME",
|
||||
Value: "$(POD_NAME)",
|
||||
},
|
||||
{
|
||||
Name: "TSRECORDER_LOGIN_SERVER",
|
||||
Value: loginServer,
|
||||
},
|
||||
}
|
||||
|
||||
for _, env := range tsr.Spec.StatefulSet.Pod.Container.Env {
|
||||
|
@ -90,7 +90,7 @@ func TestRecorderSpecs(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ss := tsrStatefulSet(tsr, tsNamespace)
|
||||
ss := tsrStatefulSet(tsr, tsNamespace, tsLoginServer)
|
||||
|
||||
// StatefulSet-level.
|
||||
if diff := cmp.Diff(ss.Annotations, tsr.Spec.StatefulSet.Annotations); diff != "" {
|
||||
@ -124,7 +124,7 @@ func TestRecorderSpecs(t *testing.T) {
|
||||
}
|
||||
|
||||
// Container-level.
|
||||
if diff := cmp.Diff(ss.Spec.Template.Spec.Containers[0].Env, env(tsr)); diff != "" {
|
||||
if diff := cmp.Diff(ss.Spec.Template.Spec.Containers[0].Env, env(tsr, tsLoginServer)); diff != "" {
|
||||
t.Errorf("(-got +want):\n%s", diff)
|
||||
}
|
||||
if diff := cmp.Diff(ss.Spec.Template.Spec.Containers[0].Image, tsr.Spec.StatefulSet.Pod.Container.Image); diff != "" {
|
||||
|
@ -25,7 +25,10 @@ import (
|
||||
"tailscale.com/tstest"
|
||||
)
|
||||
|
||||
const tsNamespace = "tailscale"
|
||||
const (
|
||||
tsNamespace = "tailscale"
|
||||
tsLoginServer = "example.tailscale.com"
|
||||
)
|
||||
|
||||
func TestRecorder(t *testing.T) {
|
||||
tsr := &tsapi.Recorder{
|
||||
@ -51,6 +54,7 @@ func TestRecorder(t *testing.T) {
|
||||
recorder: fr,
|
||||
l: zl.Sugar(),
|
||||
clock: cl,
|
||||
loginServer: tsLoginServer,
|
||||
}
|
||||
|
||||
t.Run("invalid_spec_gives_an_error_condition", func(t *testing.T) {
|
||||
@ -234,7 +238,7 @@ func expectRecorderResources(t *testing.T, fc client.WithWatch, tsr *tsapi.Recor
|
||||
role := tsrRole(tsr, tsNamespace)
|
||||
roleBinding := tsrRoleBinding(tsr, tsNamespace)
|
||||
serviceAccount := tsrServiceAccount(tsr, tsNamespace)
|
||||
statefulSet := tsrStatefulSet(tsr, tsNamespace)
|
||||
statefulSet := tsrStatefulSet(tsr, tsNamespace, tsLoginServer)
|
||||
|
||||
if shouldExist {
|
||||
expectEqual(t, fc, auth)
|
||||
|
Loading…
x
Reference in New Issue
Block a user