Skip to content

Commit

Permalink
Fix manual agent install.
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Hallgren <[email protected]>
  • Loading branch information
thallgren committed Jan 27, 2025
1 parent 7966cca commit 3be97c1
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 85 deletions.
6 changes: 2 additions & 4 deletions cmd/traffic/cmd/manager/mutator/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package mutator

import (
"github.com/telepresenceio/telepresence/v2/pkg/agentconfig"
"github.com/telepresenceio/telepresence/v2/pkg/workload"
)

const (
InjectAnnotation = workload.DomainPrefix + "inject-" + agentconfig.ContainerName
ServiceNameAnnotation = workload.DomainPrefix + "inject-service-name"
ManualInjectAnnotation = workload.DomainPrefix + "manually-injected"
InjectAnnotation = agentconfig.DomainPrefix + "inject-" + agentconfig.ContainerName
ServiceNameAnnotation = agentconfig.DomainPrefix + "inject-service-name"
)
2 changes: 1 addition & 1 deletion cmd/traffic/cmd/manager/mutator/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ func (c *configWatcher) DeleteIfMismatch(ctx context.Context, pod *core.Pod, cfg
return nil
}
a := pod.ObjectMeta.Annotations
if v, ok := a[ManualInjectAnnotation]; ok && v == "true" {
if v, ok := a[agentconfig.ManualInjectAnnotation]; ok && v == "true" {
dlog.Debugf(ctx, "Skipping pod %s because it is managed manually", pod.Name)
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/traffic/cmd/manager/mutator/workload_watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ func (c *configWatcher) updateWorkload(ctx context.Context, wl, oldWl k8sapi.Wor
return
}
tpl := wl.GetPodTemplate()
ia, ok := tpl.Annotations[workload.InjectAnnotation]
ia, ok := tpl.Annotations[agentconfig.InjectAnnotation]
if !ok {
return
}
if oldWl != nil && cmp.Equal(oldWl.GetPodTemplate(), tpl,
cmpopts.IgnoreFields(meta.ObjectMeta{}, "Namespace", "UID", "ResourceVersion", "CreationTimestamp", "DeletionTimestamp"),
cmpopts.IgnoreMapEntries(func(k, _ string) bool {
return k == workload.AnnRestartedAt
return k == agentconfig.RestartedAtAnnotation
})) {
return
}
Expand Down
42 changes: 23 additions & 19 deletions cmd/traffic/cmd/manager/state/intercept.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,23 +405,27 @@ func (s *state) ensureAgent(parentCtx context.Context, wl k8sapi.Workload, exten
}

if !managerutil.AgentInjectorEnabled(parentCtx) {
sce := mutator.GetMap(parentCtx).Get(wl.GetName(), wl.GetNamespace())
if sce != nil {
ac = sce.AgentConfig()
am := s.LoadMatchingAgents(func(_ string, ai *rpc.AgentInfo) bool {
return ai.Name == ac.AgentName && ai.Namespace == ac.Namespace
})
as = make([]*rpc.AgentInfo, len(am))
i := 0
for _, found := range am {
as[i] = found
i++
}
sortAgents(as)
return ac, as, nil
cfgJSON, ok := wl.GetPodTemplate().Annotations[agentconfig.ConfigAnnotation]
if !ok {
msg := fmt.Sprintf("agent-injector is disabled and no agent has been added manually for %s.%s", wl.GetName(), wl.GetNamespace())
return nil, nil, status.Error(codes.FailedPrecondition, msg)
}
msg := fmt.Sprintf("agent-injector is disabled and no agent has been added manually for %s.%s", wl.GetName(), wl.GetNamespace())
return nil, nil, status.Error(codes.FailedPrecondition, msg)
sce, err := agentconfig.UnmarshalJSON(cfgJSON)
if err != nil {
return nil, nil, err
}
ac = sce.AgentConfig()
am := s.LoadMatchingAgents(func(_ string, ai *rpc.AgentInfo) bool {
return ai.Name == ac.AgentName && ai.Namespace == ac.Namespace
})
as = make([]*rpc.AgentInfo, len(am))
i := 0
for _, found := range am {
as[i] = found
i++
}
sortAgents(as)
return ac, as, nil
}

if dryRun {
Expand Down Expand Up @@ -616,7 +620,7 @@ func checkInterceptAnnotations(wl k8sapi.Workload) (bool, error) {
}

webhookEnabled := true
manuallyManaged := a[mutator.ManualInjectAnnotation] == "true"
manuallyManaged := a[agentconfig.ManualInjectAnnotation] == "true"
ia := a[mutator.InjectAnnotation]
switch ia {
case "":
Expand All @@ -627,7 +631,7 @@ func checkInterceptAnnotations(wl k8sapi.Workload) (bool, error) {
default:
return false, errcat.User.Newf(
"%s is not a valid value for the %s.%s/%s annotation",
ia, wl.GetName(), wl.GetNamespace(), mutator.ManualInjectAnnotation)
ia, wl.GetName(), wl.GetNamespace(), agentconfig.ManualInjectAnnotation)
}

if !manuallyManaged {
Expand All @@ -645,7 +649,7 @@ func checkInterceptAnnotations(wl k8sapi.Workload) (bool, error) {
if an == nil {
return false, errcat.User.Newf(
"annotation %s.%s/%s=true but pod has no traffic-agent container",
wl.GetName(), wl.GetNamespace(), mutator.ManualInjectAnnotation)
wl.GetName(), wl.GetNamespace(), agentconfig.ManualInjectAnnotation)
}
return true, nil
}
Expand Down
47 changes: 5 additions & 42 deletions integration_test/manual_agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ import (
"strings"
"time"

core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"

"github.com/telepresenceio/telepresence/v2/cmd/traffic/cmd/manager/mutator"
"github.com/telepresenceio/telepresence/v2/integration_test/itest"
"github.com/telepresenceio/telepresence/v2/pkg/agentconfig"
)
Expand Down Expand Up @@ -67,6 +64,10 @@ func testManualAgent(s *itest.Suite, nsp itest.NamespacePair) {
var volumes []map[string]any
require.NoError(yaml.Unmarshal([]byte(stdout), &volumes))

stdout = itest.TelepresenceOk(ctx, "genyaml", "annotations", "--config", configFile)
var anns map[string]string
require.NoError(yaml.Unmarshal([]byte(stdout), &anns))

b, err := os.ReadFile(filepath.Join(k8sDir, "echo-manual-inject-deploy.yaml"))
require.NoError(err)
var deploy map[string]any
Expand All @@ -92,45 +93,7 @@ func testManualAgent(s *itest.Suite, nsp itest.NamespacePair) {
podSpec["containers"] = append(cons, container)
podSpec["initContainers"] = []map[string]any{initContainer}
podSpec["volumes"] = volumes
podTemplate["metadata"].(map[string]any)["annotations"] = map[string]string{mutator.ManualInjectAnnotation: "true"}

// Add the configmap entry by first retrieving the current config map
var cfgMap *core.ConfigMap
origCfgYaml, err := nsp.KubectlOut(ctx, "get", "configmap", agentconfig.ConfigMap, "-o", "yaml")
if err != nil {
cfgMap = &core.ConfigMap{
TypeMeta: meta.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: meta.ObjectMeta{
Name: agentconfig.ConfigMap,
Namespace: nsp.AppNamespace(),
},
}
origCfgYaml = ""
} else {
require.NoError(yaml.Unmarshal([]byte(origCfgYaml), &cfgMap))
}
if cfgMap.Data == nil {
cfgMap.Data = make(map[string]string)
}
cfgMap.Data[ac.WorkloadName] = cfgEntry

cfgYaml := writeYaml(agentconfig.ConfigMap+".yaml", cfgMap)
require.NoError(nsp.Kubectl(ctx, "apply", "-f", cfgYaml))
defer func() {
if origCfgYaml == "" {
require.NoError(nsp.Kubectl(ctx, "delete", "configmap", agentconfig.ConfigMap))
} else {
// Restore original configmap
cfgMap.ObjectMeta = meta.ObjectMeta{
Name: agentconfig.ConfigMap,
Namespace: nsp.AppNamespace(),
}
writeYaml(agentconfig.ConfigMap+".yaml", cfgMap)
}
}()
podTemplate["metadata"].(map[string]any)["annotations"] = anns

dplYaml := writeYaml("deployment.yaml", deploy)
require.NoError(nsp.Kubectl(ctx, "apply", "-f", dplYaml))
Expand Down
5 changes: 4 additions & 1 deletion pkg/agentconfig/sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ const (
// EnvAPIPort is the port number of the Telepresence API server, when it is enabled.
EnvAPIPort = "TELEPRESENCE_API_PORT"

DomainPrefix = "telepresence.getambassador.io/"
DomainPrefix = "telepresence.getambassador.io/"

RestartedAtAnnotation = DomainPrefix + "restartedAt"
ManualInjectAnnotation = DomainPrefix + "manually-injected"
InjectAnnotation = DomainPrefix + "inject-" + ContainerName
InjectIgnoreVolumeMounts = DomainPrefix + "inject-ignore-volume-mounts"
TerminatingTLSSecretAnnotation = DomainPrefix + "inject-terminating-tls-secret"
Expand Down
59 changes: 53 additions & 6 deletions pkg/client/cli/cmd/genyaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,12 @@ func genYAML() *cobra.Command {
Short: "Generate YAML for use in kubernetes manifests.",
Long: `Generate traffic-agent yaml for use in kubernetes manifests.
This allows the traffic agent to be injected by hand into existing kubernetes manifests.
For your modified workload to be valid, you'll have to manually inject a container and a
volume into the workload, and a corresponding configmap entry into the "telelepresence-agents"
configmap; you can do this by running "genyaml config", "genyaml container", and "genyaml volume".
For your modified workload to be valid, you'll have to manually inject annotations, a
container, and a volume into the workload; you can do this by running "genyaml config",
"genyaml container", "genyaml initcontainer", "genyaml annotations", and "genyaml volume".
NOTE: It is recommended that you not do this unless strictly necessary. Instead, we suggest letting
telepresence's webhook injector configure the traffic agents on demand.`,
RunE: func(_ *cobra.Command, _ []string) error {
return errcat.User.New("please run genyaml as \"genyaml config\", \"genyaml container\", \"genyaml initcontainer\", or \"genyaml volume\"")
},
ValidArgsFunction: cobra.NoFileCompletions,
}
flags := cmd.PersistentFlags()
Expand All @@ -62,6 +59,7 @@ telepresence's webhook injector configure the traffic agents on demand.`,
genConfigMapSubCommand(&info),
genContainerSubCommand(&info),
genInitContainerSubCommand(&info),
genVAnnotationsSubCommand(&info),
genVolumeSubCommand(&info),
)
return cmd
Expand Down Expand Up @@ -421,6 +419,55 @@ func (g *genInitContainerInfo) run(cmd *cobra.Command, kubeFlags map[string]stri
return errcat.User.New("deployment does not need an init container")
}

type genAnnotationsInfo struct {
*genYAMLCommand
}

func genVAnnotationsSubCommand(yamlInfo *genYAMLCommand) *cobra.Command {
info := genAnnotationsInfo{genYAMLCommand: yamlInfo}
kubeFlags := allKubeFlags()
cmd := &cobra.Command{
Use: "annotations",
Args: cobra.NoArgs,
Short: "Generate YAML for the pod template metadata annotations.",
Long: "Generate YAML for the pod template metadata annotations. See genyaml for more info on what this means",
RunE: func(cmd *cobra.Command, args []string) error {
return info.run(cmd, flags.Map(kubeFlags))
},
}
flags := cmd.Flags()
flags.StringVarP(&info.workloadName, "workload", "w", "",
"Name of the workload. If given, the configmap entry will be retrieved telepresence-agents configmap, mutually exclusive to --config")
flags.StringVarP(&info.configFile, "config", "c", "", "Path to the yaml containing the generated configmap entry, mutually exclusive to --workload")
flags.AddFlagSet(kubeFlags)
return cmd
}

func (g *genAnnotationsInfo) run(cmd *cobra.Command, kubeFlags map[string]string) error {
ctx := cmd.Context()
if g.configFile == "" {
var err error
ctx, err = g.WithJoinedClientSetInterface(ctx, kubeFlags)
if err != nil {
return err
}
}
cm, err := g.loadConfigMapEntry(ctx)
if err != nil {
return err
}
cmJSON, err := agentconfig.MarshalTight(cm)
if err != nil {
return err
}
annotations := map[string]string{
agentconfig.InjectAnnotation: "enabled",
agentconfig.ManualInjectAnnotation: "true",
agentconfig.ConfigAnnotation: cmJSON,
}
return g.writeObjToOutput(annotations)
}

type genVolumeInfo struct {
*genYAMLCommand
}
Expand Down
9 changes: 0 additions & 9 deletions pkg/workload/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,9 @@ package workload
import (
"k8s.io/apimachinery/pkg/runtime"

"github.com/telepresenceio/telepresence/v2/pkg/agentconfig"
"github.com/telepresenceio/telepresence/v2/pkg/k8sapi"
)

const (
DomainPrefix = "telepresence.getambassador.io/"
InjectAnnotation = DomainPrefix + "inject-" + agentconfig.ContainerName
ServiceNameAnnotation = DomainPrefix + "inject-service-name"
ManualInjectAnnotation = DomainPrefix + "manually-injected"
AnnRestartedAt = DomainPrefix + "restartedAt"
)

func FromAny(obj any) (k8sapi.Workload, bool) {
if ro, ok := obj.(runtime.Object); ok {
if wl, err := k8sapi.WrapWorkload(ro); err == nil {
Expand Down
3 changes: 2 additions & 1 deletion pkg/workload/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"k8s.io/kubectl/pkg/util/deployment"

"github.com/datawire/dlib/dlog"
"github.com/telepresenceio/telepresence/v2/pkg/agentconfig"
"github.com/telepresenceio/telepresence/v2/pkg/agentmap"
"github.com/telepresenceio/telepresence/v2/pkg/informer"
"github.com/telepresenceio/telepresence/v2/pkg/k8sapi"
Expand Down Expand Up @@ -214,7 +215,7 @@ func compareOptions() []cmp.Option {

// Ignore frequently changing annotations of no interest.
cmpopts.IgnoreMapEntries(func(k, _ string) bool {
return k == AnnRestartedAt || k == deployment.RevisionAnnotation
return k == agentconfig.RestartedAtAnnotation || k == deployment.RevisionAnnotation
}),
}
}
Expand Down

0 comments on commit 3be97c1

Please sign in to comment.