Skip to content

Commit

Permalink
fix: correctly escape extra args in kube-proxy manifest
Browse files Browse the repository at this point in the history
JSON is a subset of YAML, so we can use JSON to escape whole YAML value
to handle any kind of symbols.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
  • Loading branch information
smira authored and talos-bot committed Feb 19, 2021
1 parent 41b9f13 commit 7a6e0cd
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
15 changes: 13 additions & 2 deletions internal/app/machined/pkg/controllers/k8s/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ package k8s
import (
"bytes"
"context"
"encoding/json"
"fmt"
"html/template"
"log"
"text/template"

"github.com/AlekSi/pointer"
"github.com/talos-systems/os-runtime/pkg/controller"
Expand Down Expand Up @@ -137,6 +138,12 @@ type renderedManifest struct {
data []byte
}

func jsonify(input string) (string, error) {
out, err := json.Marshal(input)

return string(out), err
}

func (ctrl *ManifestController) render(cfg config.K8sManifestsSpec, scrt *secrets.RootKubernetesSpec) ([]renderedManifest, error) {
templateConfig := struct {
config.K8sManifestsSpec
Expand Down Expand Up @@ -191,7 +198,11 @@ func (ctrl *ManifestController) render(cfg config.K8sManifestsSpec, scrt *secret
manifests := make([]renderedManifest, len(defaultManifests))

for i := range defaultManifests {
tmpl, err := template.New(defaultManifests[i].name).Parse(string(defaultManifests[i].template))
tmpl, err := template.New(defaultManifests[i].name).
Funcs(template.FuncMap{
"json": jsonify,
}).
Parse(string(defaultManifests[i].template))
if err != nil {
return nil, fmt.Errorf("error parsing manifest template %q: %w", defaultManifests[i].name, err)
}
Expand Down
45 changes: 45 additions & 0 deletions internal/app/machined/pkg/controllers/k8s/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,51 @@ func (suite *ManifestSuite) TestReconcileDisableKubeProxy() {
))
}

func (suite *ManifestSuite) TestReconcileKubeProxyExtraArgs() {
rootSecrets := secrets.NewRoot(secrets.RootKubernetesID)
manifestConfig := config.NewK8sManifests()
spec := defaultManifestSpec
spec.ProxyExtraArgs = map[string]string{
"bind-address": "\"::\"",
}
manifestConfig.SetManifests(spec)

suite.Require().NoError(suite.state.Create(suite.ctx, rootSecrets))
suite.Require().NoError(suite.state.Create(suite.ctx, manifestConfig))

suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertManifests(
[]string{
"00-kubelet-bootstrapping-token",
"01-csr-approver-role-binding",
"01-csr-node-bootstrap",
"01-csr-renewal-role-binding",
"02-kube-system-sa-role-binding", "03-default-pod-security-policy", "05-flannel",
"10-kube-proxy",
"11-core-dns",
"11-core-dns-svc",
"11-kube-config-in-cluster",
},
)
},
))

r, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.ControlPlaneNamespaceName, k8s.ManifestType, "10-kube-proxy", resource.VersionUndefined))
suite.Require().NoError(err)

manifest := r.(*k8s.Manifest) //nolint: errcheck
suite.Assert().Len(manifest.Objects(), 3)

suite.Assert().Equal("DaemonSet", manifest.Objects()[0].GetKind())

ds := manifest.Objects()[0].Object
containerSpec := ds["spec"].(map[string]interface{})["template"].(map[string]interface{})["spec"].(map[string]interface{})["containers"].([]interface{})[0]
args := containerSpec.(map[string]interface{})["command"].([]interface{}) //nolint: errcheck

suite.Assert().Equal("--bind-address=\"::\"", args[len(args)-1])
}

func (suite *ManifestSuite) TearDownTest() {
suite.T().Log("tear down")

Expand Down
2 changes: 1 addition & 1 deletion internal/app/machined/pkg/controllers/k8s/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ spec:
- --proxy-mode={{ .ProxyMode }}
- --conntrack-max-per-core=0
{{- range $k, $v := .ProxyExtraArgs }}
- --{{ $k }}={{ $v }}
- {{ printf "--%s=%s" $k $v | json }}
{{- end }}
env:
- name: NODE_NAME
Expand Down
3 changes: 0 additions & 3 deletions pkg/resources/k8s/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"encoding/json"
"fmt"
"io"
"log"

"github.com/talos-systems/os-runtime/pkg/resource"
"github.com/talos-systems/os-runtime/pkg/resource/core"
Expand Down Expand Up @@ -122,8 +121,6 @@ func (r *Manifest) SetYAML(yamlBytes []byte) error {
continue
}

log.Printf("jsonManifest = %v", string(jsonManifest))

obj := new(unstructured.Unstructured)

if err = json.Unmarshal(jsonManifest, obj); err != nil {
Expand Down

0 comments on commit 7a6e0cd

Please sign in to comment.