Skip to content

Commit a54c836

Browse files
authored
feat: add policy subcommand to render a vault policy without an approle backend (#38)
fix: add concept of policy definition without approle to support policy creation fix: update allowed operations to include sudo --------- Signed-off-by: Ben Stickel <[email protected]>
1 parent 9f6b47e commit a54c836

File tree

4 files changed

+124
-2
lines changed

4 files changed

+124
-2
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Licensed to Elasticsearch B.V. under one or more contributor
2+
// license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright
4+
// ownership. Elasticsearch B.V. licenses this file to you under
5+
// the Apache License, Version 2.0 (the "License"); you may
6+
// not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package cmd
19+
20+
import (
21+
"io"
22+
23+
"github.com/spf13/cobra"
24+
"go.uber.org/zap"
25+
26+
"github.com/elastic/harp-plugins/terraformer/pkg/terraformer"
27+
"github.com/elastic/harp/pkg/sdk/cmdutil"
28+
"github.com/elastic/harp/pkg/sdk/log"
29+
)
30+
31+
var (
32+
terraformerPolicyInputSpec string
33+
terraformerPolicyOutputPath string
34+
terraformerPolicyEnvironment string
35+
)
36+
37+
// -----------------------------------------------------------------------------
38+
39+
var terraformerPolicyCmd = func() *cobra.Command {
40+
cmd := &cobra.Command{
41+
Use: "policy",
42+
Short: "Policy generator for Harp CSO Vault",
43+
Run: runTerraformerPolicy,
44+
}
45+
46+
// Parameters
47+
cmd.Flags().StringVar(&terraformerPolicyInputSpec, "spec", "-", "AppRole specification path ('-' for stdin or filename)")
48+
cmd.Flags().StringVar(&terraformerPolicyOutputPath, "out", "-", "Output file ('-' for stdout or a filename)")
49+
cmd.Flags().StringVar(&terraformerPolicyEnvironment, "env", "production", "Target environment")
50+
51+
return cmd
52+
}
53+
54+
func runTerraformerPolicy(cmd *cobra.Command, _ []string) {
55+
ctx, cancel := cmdutil.Context(cmd.Context(), "harp-terraformer-policy", conf.Debug.Enable, conf.Instrumentation.Logs.Level)
56+
defer cancel()
57+
58+
var (
59+
reader io.Reader
60+
err error
61+
)
62+
63+
// Create input reader
64+
reader, err = cmdutil.Reader(terraformerPolicyInputSpec)
65+
if err != nil {
66+
log.For(ctx).Fatal("unable to open input specification", zap.Error(err), zap.String("path", terraformerPolicyInputSpec))
67+
}
68+
69+
// Create output writer
70+
writer, err := cmdutil.Writer(terraformerPolicyOutputPath)
71+
if err != nil {
72+
log.For(ctx).Fatal("unable to create output writer", zap.Error(err), zap.String("path", terraformerPolicyOutputPath))
73+
}
74+
75+
// Run terraformer
76+
if err := terraformer.Run(ctx, reader, terraformerPolicyEnvironment, true, terraformer.PolicyTemplate, writer); err != nil {
77+
log.For(ctx).Fatal("unable to process specification", zap.Error(err), zap.String("path", terraformerPolicyInputSpec))
78+
}
79+
}

terraformer/cmd/harp-terraformer/internal/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ var mainCmd = func() *cobra.Command {
5757

5858
// Add subcommands
5959
cmd.AddCommand(terraformerAgentCmd())
60+
cmd.AddCommand(terraformerPolicyCmd())
6061
cmd.AddCommand(terraformerServiceCmd())
6162

6263
// Return command

terraformer/pkg/terraformer/compiler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ var allowedCapabilities = types.StringArray{
209209
"read",
210210
"update",
211211
"delete",
212+
"sudo",
212213
}
213214

214215
// filterCapabilities removes useless capabilities

terraformer/pkg/terraformer/templates.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package terraformer
1919

2020
import terraformerv1 "github.com/elastic/harp-plugins/terraformer/api/gen/go/harp/terraformer/v1"
2121

22-
// ServiceTemplate is the TF 0.12 Service template.
22+
// ServiceTemplate is the TF >=0.12 Service template.
2323
const ServiceTemplate = `# Generated with Harp Terraformer, Don't modify.
2424
# https://github.com/elastic/harp-plugins/tree/main/cmd/harp-terraformer
2525
# ---
@@ -74,7 +74,7 @@ resource "vault_approle_auth_backend_role" "{{.ObjectName}}" {
7474
}
7575
`
7676

77-
// AgentTemplate is the TF 0.12 Agent template.
77+
// AgentTemplate is the TF >=0.12 Agent template.
7878
const AgentTemplate = `# Generated with Harp Terraformer, Don't modify.
7979
# https://github.com/elastic/harp-plugins/tree/main/cmd/harp-terraformer
8080
# ---
@@ -127,6 +127,47 @@ resource "vault_approle_auth_backend_role" "agent-{{.ObjectName}}" {
127127
}
128128
`
129129

130+
// PolicyTemplate is the TF >=0.12 Agent template.
131+
const PolicyTemplate = `# Generated with Harp Terraformer, Don't modify.
132+
# https://github.com/elastic/harp-plugins/tree/main/cmd/harp-terraformer
133+
# ---
134+
# SpecificationHash: "{{.SpecHash}}"
135+
# Owner: "{{.Meta.Owner}}"
136+
# Date: "{{.Date}}"
137+
# Description: "{{.Meta.Description}}"
138+
# Issues:{{range .Meta.Issues}}
139+
# - {{.}}{{ end }}
140+
# ---
141+
#
142+
# ------------------------------------------------------------------------------
143+
144+
# Create the policy
145+
data "vault_policy_document" "policy-{{.ObjectName}}" {
146+
{{- range $ns, $secrets := .Namespaces }}
147+
# {{ $ns }} secrets{{ range $k, $item := $secrets }}
148+
rule {
149+
description = "{{$item.Description}}"
150+
path = "{{$item.Path}}"
151+
capabilities = [{{range $i, $v := $item.Capabilities}}{{if $i}} ,{{end}}{{printf "%q" $v}}{{end}}]
152+
}
153+
{{end -}}
154+
{{end}}{{if .CustomRules }}
155+
# Custom secret paths{{ range $k, $item := .CustomRules }}
156+
rule {
157+
description = "{{$item.Description}}"
158+
path = "{{$item.Path}}"
159+
capabilities = [{{range $i, $v := $item.Capabilities}}{{if $i}} ,{{end}}{{printf "%q" $v}}{{end}}]
160+
}
161+
{{end}}{{end -}}
162+
}
163+
164+
# Register the policy
165+
resource "vault_policy" "policy-{{.ObjectName}}" {
166+
name = "policy-{{.ObjectName}}"
167+
policy = data.vault_policy_document.policy-{{.ObjectName}}.hcl
168+
}
169+
`
170+
130171
// -----------------------------------------------------------------------------
131172

132173
type tmplModel struct {

0 commit comments

Comments
 (0)