Skip to content
Merged
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
14 changes: 5 additions & 9 deletions cmd/cluster/dynatrace/logsCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,22 @@ var (

func NewCmdLogs() *cobra.Command {
logsCmd := &cobra.Command{
Use: "logs",
Use: "logs <cluster-id>",
Short: "Fetch logs from Dynatrace",
Args: cobra.NoArgs,
Args: cobra.ExactArgs(1),
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
err := main()
err := main(args[0])
if err != nil {
cmdutil.CheckErr(err)
}
},
}

// set cluster flag as required
logsCmd.MarkFlagRequired("cluster")

logsCmd.Flags().BoolVar(&dryRun, "dry-run", false, "Only builds the query without fetching any logs from the tenant")
logsCmd.Flags().IntVar(&tail, "tail", 100, "Last 'n' logs to fetch (defaults to 100)")
logsCmd.Flags().IntVar(&since, "since", 1, "Number of hours (integer) since which to search (defaults to 1 hour)")
logsCmd.Flags().StringVar(&contains, "contains", "", "Include logs which contain a phrase")
logsCmd.Flags().StringVar(&cluster, "cluster", "", "Cluster identifier (name / internal ID / external ID) to search")
logsCmd.Flags().StringVar(&sortOrder, "sort", "desc", "Sort the results by timestamp in either ascending or descending order. Accepted values are 'asc' and 'desc'")
logsCmd.Flags().BoolVar(&hcp, "hcp", false, "Set true to Include the HCP Namespace")
logsCmd.Flags().StringSliceVar(&namespaceList, "namespace", []string{}, "Namespace(s) (comma-separated)")
Expand All @@ -60,12 +56,12 @@ func getLinkToWebConsole(dtURL string, since int, base64Url string) string {
return fmt.Sprintf("\nLink to Web Console - \n%sui/apps/dynatrace.classic.logs.events/ui/logs-events?gtf=-%dh&gf=all&sortDirection=desc&advancedQueryMode=true&isDefaultQuery=false&visualizationType=table#%s\n\n", dtURL, since, base64Url)
}

func main() error {
func main(clusterID string) error {
if since <= 0 {
return fmt.Errorf("invalid time duration")
}

clusterInternalID, mgmtClusterName, DTURL, err := fetchClusterDetails(cluster)
clusterInternalID, mgmtClusterName, DTURL, err := fetchClusterDetails(clusterID)
if err != nil {
return fmt.Errorf("failed to acquire cluster details %v", err)
}
Expand Down
22 changes: 14 additions & 8 deletions cmd/cluster/dynatrace/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import (

const (
authURL string = "https://sso.dynatrace.com/sso/oauth2/token"
clientIDKey string = "dt_client_id_key"
DTVaultPath string = "dt_vault_path"
VaultAddr string = "vault_address"
)

type Requester struct {
Expand Down Expand Up @@ -65,22 +66,27 @@ func (rh *Requester) send() (string, error) {
return string(body), nil
}

func getClientID() (id string, error error) {
if !viper.IsSet(clientIDKey) {
return "", fmt.Errorf("key %s is not set in config file", clientIDKey)
func getVaultPath() (addr, path string, error error) {
if !viper.IsSet(VaultAddr) {
return "", "", fmt.Errorf("key %s is not set in config file", VaultAddr)
}
clientID := viper.GetString(clientIDKey)
vaultAddr := viper.GetString(VaultAddr)

return clientID, nil
if !viper.IsSet(DTVaultPath) {
return "", "", fmt.Errorf("key %s is not set in config file", DTVaultPath)
}
vaultPath := viper.GetString(DTVaultPath)

return vaultAddr, vaultPath, nil
}

func getAccessToken() (string, error) {
clientID, err := getClientID()
vaultAddr, vaultPath, err := getVaultPath()
if err != nil {
return "", err
}

clientSecret, err := getSecretFromVault(clientID)
clientID, clientSecret, err := getSecretFromVault(vaultAddr, vaultPath)
if err != nil {
return "", err
}
Expand Down
34 changes: 16 additions & 18 deletions cmd/cluster/dynatrace/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,50 @@ import (
"os/exec"
)

const (
path string = "osd-sre/dynatrace/sd-sre-platform-oauth-client-grail"
address string = "https://vault.devshift.net"
)

type response struct {
Data struct {
Data map[string]interface{} `json:"data"`
} `json:"data"`
}

func getSecretFromVault(clientID string) (secret string, error error) {
err := os.Setenv("VAULT_ADDR", address)
func getSecretFromVault(vaultAddr, vaultPath string) (id string, secret string, error error) {
err := os.Setenv("VAULT_ADDR", vaultAddr)
if err != nil {
fmt.Printf("Error setting environment variable: %v\n", err)
return "", err
return "", "", err
}
cmd := exec.Command("vault", "login", "-method=oidc", "-no-print")
cmd.Stdout = nil
cmd.Stderr = nil
if err = cmd.Run(); err != nil {
fmt.Println("Error running 'vault login':", err)
return "", nil
return "", "", nil
}

err = os.Setenv("VAULT_ADDR", address)
err = os.Setenv("VAULT_ADDR", vaultAddr)
if err != nil {
return "", fmt.Errorf("error setting environment variable: %v", err)
return "", "", fmt.Errorf("error setting environment variable: %v", err)
}

kvGetCommand := exec.Command("vault", "kv", "get", "-format=json", path)
kvGetCommand := exec.Command("vault", "kv", "get", "-format=json", vaultPath)
output, err := kvGetCommand.Output()
if err != nil {
fmt.Println("Error running 'vault kv get':", err)
return "", nil
return "", "", nil
}

var resp response
if err := json.Unmarshal(output, &resp); err != nil {
return "", fmt.Errorf("error unmarshaling JSON response: %v", err)
return "", "", fmt.Errorf("error unmarshaling JSON response: %v", err)
}

secretData, ok := resp.Data.Data[clientID].(string)
clientID, ok := resp.Data.Data["client_id"].(string)
if !ok {
return "", "", fmt.Errorf("error extracting secret data from JSON response")
}
clientSecret, ok := resp.Data.Data["client_secret"].(string)
if !ok {
return "", fmt.Errorf("error extracting secret data from JSON response")
return "", "", fmt.Errorf("error extracting secret data from JSON response")
}

return secretData, nil
return clientID, clientSecret, nil
}