Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds mithrilctl initial implementation #24

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions POC/spire/spire-agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ rules:
- apiGroups: [""]
resources: ["pods","nodes","nodes/proxy"]
verbs: ["get"]

---
# Binds above cluster role to spire-agent service account
kind: ClusterRoleBinding
Expand Down Expand Up @@ -86,7 +85,6 @@ data:
live_path = "/live"
ready_path = "/ready"
}

---
apiVersion: apps/v1
kind: DaemonSet
Expand Down
2 changes: 1 addition & 1 deletion POC/spire/spire-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ data:
data_dir = "/run/spire/server/data"
log_level = "DEBUG"
ca_key_type = "rsa-2048"

federation {
bundle_endpoint {
address = "0.0.0.0"
Expand Down
30 changes: 30 additions & 0 deletions mithrilctl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# mithrilctl

Mithrilctl is a tool to easily deploy Mithril in a cluster.

## Requirements

1. kubectl
2. helm
3. A running cluster

## Setting up mithrilctl

At first, you need to build the mithrilctl binary. You can move it to the binary directory in order to be able to use it everywhere you need.

```bash
cd <Mithril repository path>/mithrilctl && go build -o mithril && sudo mv mithril /usr/local/bin/mithril
```

## Install Mithril

```bash
$ mithril install
```

## Getting installed manifests

```bash
$ mithril get manifest --spire
$ mithril get manifest --istio
```
34 changes: 34 additions & 0 deletions mithrilctl/cmd/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cmd

import (
"os"

"github.com/spf13/cobra"
)

// getCmd represents the get command
var getCmd = &cobra.Command{
Use: "get",
Short: "Gets resources definitions ",
Long: `Command used for outputing a helm release manifest`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 || args[0] == "" {
cmd.Help()
os.Exit(0)
}
},
}

func init() {
rootCmd.AddCommand(getCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// getCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// getCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
71 changes: 71 additions & 0 deletions mithrilctl/cmd/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cmd

import (
"fmt"
"github.com/spf13/cobra"
"mithril/pkg/istio"
"mithril/pkg/spire"
"mithril/util"
"os"
"time"
)

var spinner = util.NewSpinner(os.Stderr)

// installCmd represents the install command
var installCmd = &cobra.Command{
Use: "install",
Short: "Installs Mithril",
Long: `Command used to install Istio integrated with SPIRE on a Kubernetes cluster`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(fmt.Sprintf(" %s ", "Installing Mithril ⚒️ ..."))
spinner.SetSuffix(fmt.Sprintf(" %s ", "Deploying SPIRE 🗝️"))
go func() {
spinner.Start()
}()

time.Sleep(time.Millisecond * 500)
err := spire.DeploySpire()
fmt.Fprint(spinner.Writer, "\r")
successFormat := " \x1b[32m✓\x1b[0m %s\n"
failureFormat := " \033[31mx\x1b[0m %s\n"

if err != nil {
fmt.Fprintf(spinner.Writer, failureFormat, "Deploying SPIRE 🗝️")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we get an error, why does it print "Deploying SPIRE"?

} else {
fmt.Fprintf(spinner.Writer, successFormat, "Deploying SPIRE 🗝️")
}
spinner.Stop()
spinner.SetSuffix(fmt.Sprintf(" %s ", "Deploying Istio 🛡️"))
go func() {
spinner.Start()
}()

time.Sleep(time.Millisecond * 500)
err = istio.DeployIstio()
fmt.Fprint(spinner.Writer, "\r")
if err != nil {
fmt.Fprintf(spinner.Writer, failureFormat, "Deploying Istio 🛡️")
} else {
fmt.Fprintf(spinner.Writer, successFormat, "Deploying Istio 🛡️")
}
spinner.Stop()
if err == nil {
fmt.Fprintf(spinner.Writer, "\nIstio automatic injection is enabled in all namespaces!\nStart using Mithril by deploying a workload\n")
}
},
}

func init() {
rootCmd.AddCommand(installCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// installCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// installCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
98 changes: 98 additions & 0 deletions mithrilctl/cmd/manifest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package cmd

import (
"fmt"
"os"
"strings"

"github.com/spf13/cobra"
"k8s.io/utils/exec"
)

// manifestCmd represents the manifest command
var manifestCmd = &cobra.Command{
Use: "manifest",
Short: "Get manifest from a helm release",
Long: `Command for getting helm manifests from releases`,
Run: func(cmd *cobra.Command, args []string) {
spiref, _ := cmd.Flags().GetBool("spire")
istiof, _ := cmd.Flags().GetBool("istio")
Comment on lines +18 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spireFlag and istioFlag?

if !spiref && !istiof {
cmd.Help()
os.Exit(0)
}
if spiref {
command := fmt.Sprintf("get manifest spire-server")
cmdArgs := strings.Fields(command)
cmd := exec.New()
spireInstall := cmd.Command("helm", cmdArgs[0:]...)
out, err := spireInstall.CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "\nerror getting SPIRE server manifest err: %s", err)
}
fmt.Fprintf(os.Stdout, "# SPIRE-Server manifest\n")
fmt.Fprintf(os.Stdout, "%s", out)

command = fmt.Sprintf("get manifest spire-agent")
cmdArgs = strings.Fields(command)
cmd = exec.New()
spireInstall = cmd.Command("helm", cmdArgs[0:]...)
out, err = spireInstall.CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "\nerror getting SPIRE agent manifest err: %s", err)
}
fmt.Fprintf(os.Stdout, "# SPIRE-Agent manifest\n")
fmt.Fprintf(os.Stdout, "%s", out)
}

if istiof {
command := fmt.Sprintf("get manifest base")
cmdArgs := strings.Fields(command)
cmd := exec.New()
spireInstall := cmd.Command("helm", cmdArgs[0:]...)
out, err := spireInstall.CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "\nerror getting istio base manifest err: %s", err)
}
fmt.Fprintf(os.Stdout, "# Istio base manifest\n")
fmt.Fprintf(os.Stdout, "%s", out)

command = fmt.Sprintf("get manifest istiod -n istio-system")
cmdArgs = strings.Fields(command)
cmd = exec.New()
spireInstall = cmd.Command("helm", cmdArgs[0:]...)
out, err = spireInstall.CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "\nerror getting istiod manifest err: %s", err)
}
fmt.Fprintf(os.Stdout, "# Istio istiod manifest\n")
fmt.Fprintf(os.Stdout, "%s", out)

command = fmt.Sprintf("get manifest ingressgateway -n istio-system")
cmdArgs = strings.Fields(command)
cmd = exec.New()
spireInstall = cmd.Command("helm", cmdArgs[0:]...)
out, err = spireInstall.CombinedOutput()
if err != nil {
fmt.Fprintf(os.Stderr, "\nerror getting istio ingressgateway manifest err: %s", err)
}
fmt.Fprintf(os.Stdout, "# Istio ingressgateway manifest\n")
fmt.Fprintf(os.Stdout, "%s", out)
}
},
}

func init() {
getCmd.AddCommand(manifestCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// manifestCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
manifestCmd.Flags().BoolP("spire", "", false, "Selects spire manifests")
manifestCmd.Flags().BoolP("istio", "", false, "Selects istio manifests")
}
65 changes: 65 additions & 0 deletions mithrilctl/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cmd

import (
"fmt"
"github.com/spf13/cobra"
"mithril/pkg"
"os"
)

var cfgFile string

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "mithril",
Short: "CLI tool to simplify Mithril deployment",
Long: `Mithril configuration command line utility for managing SPIRE and Istio installations`,
// Uncomment the following line if your bare application
// has an action associated with it:
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
os.Exit(0)
}
},
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

func init() {
cobra.OnInitialize(initConfig)

// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
rootCmd.CompletionOptions.DisableDefaultCmd = true
//rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.mithril.yaml)")

// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig adds and updates Mithril helm charts
func initConfig() {
// adds Mithril helm charts
err := pkg.AddMithril()
if err != nil {
fmt.Printf(err.Error())
os.Exit(1)
}

// updates Mithril helm charts
err = pkg.UpdateMithril()
if err != nil {
fmt.Printf(err.Error())
os.Exit(1)
}
}
Loading