Skip to content

Commit

Permalink
Add DRS support and update logging
Browse files Browse the repository at this point in the history
  • Loading branch information
martezr committed Oct 19, 2022
1 parent 659f806 commit b9d495f
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 50 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
vauth
vauth.db
config.yaml
main.tf
terraform.*
vault.tf
install.sh
vauth-vault-agent-helper
.terraform
12 changes: 6 additions & 6 deletions approle/approle.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"crypto/tls"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"time"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/api"
"github.com/martezr/vauth/utils"
)
Expand Down Expand Up @@ -49,7 +49,7 @@ func FetchAppRole(config utils.Config, vaultAddr string, token string, rolename
}

if !pathExists {
log.Printf("unable to find %s mount point", config.VaultAppRoleMount)
hclog.Default().Info(fmt.Sprintf("unable to find %s mount point", config.VaultAppRoleMount))
return "role not found", "", "", ""
}

Expand All @@ -59,7 +59,7 @@ func FetchAppRole(config utils.Config, vaultAddr string, token string, rolename
logError(roleerr)

if roles == nil {
log.Printf("%s contains no roles", config.VaultAppRoleMount)
hclog.Default().Info(fmt.Sprintf("%s contains no roles", config.VaultAppRoleMount))
return "role not found", "", "", ""
}

Expand Down Expand Up @@ -98,10 +98,10 @@ func FetchAppRole(config utils.Config, vaultAddr string, token string, rolename

if config.VaultWrapResponse {
if secretdata == nil {
log.Println("nil secret")
hclog.Default().Named("vault").Warn("nil secret")
}
if secretdata.WrapInfo == nil {
log.Println("nil wrap info")
hclog.Default().Named("vault").Warn("nil wrap info")
}

token := secretdata.WrapInfo.Token
Expand All @@ -124,6 +124,6 @@ func FetchAppRole(config utils.Config, vaultAddr string, token string, rolename
// logError logs error messages
func logError(errormessage error) {
if errormessage != nil {
log.Println(errormessage)
hclog.Default().Named("vault").Error(errormessage.Error())
}
}
3 changes: 2 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"

"github.com/hashicorp/go-hclog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -43,6 +44,6 @@ func initConfig() {

// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
hclog.Default().Info(fmt.Sprintf("Using config file: %s", viper.ConfigFileUsed()))
}
}
72 changes: 46 additions & 26 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"strconv"
"time"

hclog "github.com/hashicorp/go-hclog"
"github.com/martezr/vauth/approle"
"github.com/martezr/vauth/database"
"github.com/martezr/vauth/utils"
Expand Down Expand Up @@ -49,6 +50,7 @@ func clientHandler() http.Handler {

func init() {
rootCmd.AddCommand(serverCmd)
serverCmd.Flags().BoolP("debug", "d", false, "Help message for toggle")
}

var serverCmd = &cobra.Command{
Expand All @@ -61,7 +63,6 @@ var serverCmd = &cobra.Command{
}

func server() {
log.Println("starting vAuth 0.0.1")
cfg := viper.New()
if cfgFile != "" {
cfg.SetConfigFile(cfgFile)
Expand All @@ -76,13 +77,13 @@ func server() {
if err := cfg.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; ignore error if desired
log.Println("No config file found")
hclog.Default().Named("core").Error("No config file found")
}
}

err := cfg.Unmarshal(&config)
if err != nil {
log.Fatalf("unable to decode into struct, %v", err)
hclog.Default().Named("core").Error(fmt.Sprintf("unable to decode into struct, %v", err))
}

// Creating a connection context
Expand All @@ -102,31 +103,48 @@ func server() {
config.VaultToken = cfg.GetString("vault_token")
config.VaultWrapResponse = cfg.GetBool("vault_wrap_response")

fmt.Println("==> Vauth server configuration:")
fmt.Println("")
mess := fmt.Sprintf(
"%24s: %s",
"API Address",
fmt.Sprintf("0.0.0.0:%s", config.UIPort))
fmt.Println(mess)
vauthVersion := fmt.Sprintf(
"%24s: %s",
"Version",
"vAuth v0.0.2")
fmt.Println(vauthVersion)
fmt.Println("")
fmt.Println("==> Vauth server started! Log data will stream in below:")
fmt.Println("")

vcenterURL, err := url.Parse(fmt.Sprintf("https://%v/sdk", config.VsphereServer))
if err != nil {
log.Println(err)
hclog.Default().Named("vsphere").Error(err.Error())
}
credentials := url.UserPassword(config.VsphereUsername, config.VspherePassword)
vcenterURL.User = credentials

// Connecting to vCenter
log.Print("connecting to vCenter server")
hclog.Default().Named("vsphere").Info("connecting to vCenter server")

vsphereClient, err = govmomi.NewClient(ctx, vcenterURL, true)
if err != nil {
log.Fatal(err)
hclog.Default().Named("vsphere").Error(err.Error())
}
log.Printf("connected to vCenter: %s", config.VsphereServer)
hclog.Default().Named("vsphere").Info(fmt.Sprintf("connected to vCenter: %s", config.VsphereServer))
finder := find.NewFinder(vsphereClient.Client, true)
db = database.StartDB(config.DataDir)

for _, datacenter := range config.VsphereDatacenters {
// Iterate through dcs
dc, err := finder.DatacenterOrDefault(ctx, datacenter)
if err != nil {
log.Println(err)
hclog.Default().Named("vsphere").Error(err.Error())
}
log.Println(dc)

hclog.Default().Named("vsphere").Info(fmt.Sprintf("connected to vSphere datacenter: %s", dc.Name()))

finder.SetDatacenter(dc)
refs := []types.ManagedObjectReference{dc.Reference()}
Expand All @@ -139,7 +157,7 @@ func server() {
}
}

log.Println("ui listening on port", config.UIPort)
hclog.Default().Named("core").Info(fmt.Sprintf("ui listening on port %s", config.UIPort))
port := fmt.Sprintf(":%s", config.UIPort)

http.Handle("/", http.StripPrefix("/", clientHandler()))
Expand All @@ -164,7 +182,7 @@ func GetVsphereHealthStatus() string {
vSphereURL := fmt.Sprintf("https://%s", config.VsphereServer)
resp, err := httpClient.Get(vSphereURL)
if err != nil {
log.Println(err)
hclog.Default().Named("core").Error(err.Error())
return "unhealthy"
}
if resp.StatusCode == 200 {
Expand All @@ -186,7 +204,7 @@ func GetVaultHealthStatus() string {
VaultURL := fmt.Sprintf("%s/v1/sys/health", config.VaultAddress)
resp, err := httpClient.Get(VaultURL)
if err != nil {
log.Println(err)
hclog.Default().Named("core").Error(err.Error())
return "unhealthy"
}
if resp.StatusCode == 200 {
Expand Down Expand Up @@ -221,9 +239,9 @@ func handleEvent(ref types.ManagedObjectReference, events []types.BaseEvent) (er
for _, event := range events {
eventType := reflect.TypeOf(event).String()
// Detect VM power on events
if eventType == "*types.VmPoweredOnEvent" {
if eventType == "*types.VmPoweredOnEvent" || eventType == "*types.DrsVmPoweredOnEvent" {
vmName := event.GetEvent().Vm.Name
log.Printf("detected power on event for %s", vmName)
hclog.Default().Named("vsphere").Info(fmt.Sprintf("detected power on event for %s", vmName))
eventID := fmt.Sprintf("%d", event.GetEvent().ChainId)
if isUnprocessedEvent(event) {
role := updateVM(config.VaultAddress, config.VaultToken, vmName, event.GetEvent().Datacenter.Name)
Expand All @@ -239,7 +257,7 @@ func handleEvent(ref types.ManagedObjectReference, events []types.BaseEvent) (er
// Detect VM custom attribute change
if eventType == "*types.CustomFieldValueChangedEvent" {
vmName := event.GetEvent().Vm.Name
log.Printf("detected custom attribute change event for %s", vmName)
hclog.Default().Named("vsphere").Info(fmt.Sprintf("detected custom attribute change event for %s", vmName))
eventID := fmt.Sprintf("%d", event.GetEvent().ChainId)
if isUnprocessedEvent(event) {
role := updateVM(config.VaultAddress, config.VaultToken, vmName, event.GetEvent().Datacenter.Name)
Expand All @@ -255,9 +273,9 @@ func handleEvent(ref types.ManagedObjectReference, events []types.BaseEvent) (er
// Detect VM removal events
if eventType == "*types.VmRemovedEvent" {
vmName := event.GetEvent().Vm.Name
log.Printf("detected remove event for %s", vmName)
hclog.Default().Named("vsphere").Info(fmt.Sprintf("detected remove event for %s", vmName))
if isUnprocessedEvent(event) {
log.Printf("Delete VM: %s", vmName)
hclog.Default().Named("vsphere").Info(fmt.Sprintf("delete virtual machine: %s", vmName))
database.DeleteDBRecord(db, vmName)
}
}
Expand All @@ -270,15 +288,15 @@ func isUnprocessedEvent(event types.BaseEvent) (response bool) {
eventID := fmt.Sprintf("%d", event.GetEvent().ChainId)
eventIDInt, err := strconv.Atoi(eventID)
if err != nil {
log.Println(err)
hclog.Default().Named("core").Error(err.Error())
}
evalData := database.ViewDBRecord(db, vmName)
var evalParse utils.VMRecord
var evalID string
if evalData != "" {
err = json.Unmarshal([]byte(evalData), &evalParse)
if err != nil {
log.Println(err)
hclog.Default().Named("core").Error(err.Error())
}
evalID = evalParse.LatestEventId
} else {
Expand All @@ -290,7 +308,7 @@ func isUnprocessedEvent(event types.BaseEvent) (response bool) {
} else {
evalIDInt, err = strconv.Atoi(evalID)
if err != nil {
log.Println(err)
hclog.Default().Named("core").Error(err.Error())
}
}

Expand All @@ -300,6 +318,7 @@ func isUnprocessedEvent(event types.BaseEvent) (response bool) {
return false
}

// updateVM updates the virtual machine with the secret material returned from vault
func updateVM(vaultAddr string, token string, vmname string, datacenter string) (role string) {
// Creating a connection context
ctx, cancel := context.WithCancel(context.Background())
Expand All @@ -309,14 +328,14 @@ func updateVM(vaultAddr string, token string, vmname string, datacenter string)

vsphereDatacenter, err := finder.DatacenterOrDefault(ctx, datacenter)
if err != nil {
log.Println(err)
hclog.Default().Named("vsphere").Error(err.Error())
}

finder.SetDatacenter(vsphereDatacenter)

machines, err := finder.VirtualMachineList(ctx, vmname)
if err != nil {
log.Println(err)
hclog.Default().Named("vsphere").Error(err.Error())
}
// Fetch IAM Role information
attkey, _ := object.GetCustomFieldsManager(vsphereClient.Client)
Expand All @@ -336,7 +355,7 @@ func updateVM(vaultAddr string, token string, vmname string, datacenter string)
customAttrs[fmt.Sprint(fv.GetCustomFieldValue().Key)] = value
}
if fv.GetCustomFieldValue().Key == attID {
log.Printf("found the %s role associated with %s", value, vmname)
hclog.Default().Named("vsphere").Info(fmt.Sprintf("found the %s role associated with %s", value, vmname))
role = value
}
}
Expand All @@ -355,13 +374,14 @@ func updateVM(vaultAddr string, token string, vmname string, datacenter string)
ExtraConfig: settings,
}
vmdata.Reconfigure(ctx, authSpec)
log.Printf("updated VM: %s", vmname)
hclog.Default().Named("vsphere").Info(fmt.Sprintf("updated virtual machine: %s", vmname))
}
if status == "role not found" {
log.Printf("the %s role associated with %s does not exist in Vault", role, vmname)
hclog.Default().Named("vault").Info(fmt.Sprintf("the %s role associated with %s does not exist in Vault", role, vmname))
}
} else {
log.Printf("no role associated with %s", vmname)
hclog.Default().Named("vsphere").Warn(fmt.Sprintf("no role associated with %s", vmname))

}
}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/webui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ <h2 class="text-gray-800 font-bold mb-4">Status Overview</h2>
<div class="lg:w-1/3 mb-4 lg:mb-0 px-2">
<div class="w-full flex items-center h-40 px-6 rounded-lg">
<div class="w-full">
<div class="flex justify-center mb-2">
<div class="flex justify-center my-4">
<span class="block font-light">
Version
</span>
Expand Down

0 comments on commit b9d495f

Please sign in to comment.