Skip to content

Commit

Permalink
get token from vault
Browse files Browse the repository at this point in the history
  • Loading branch information
Vivek Reddy committed Oct 24, 2024
1 parent b9b97de commit eb2d5fc
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 16 deletions.
48 changes: 34 additions & 14 deletions pkg/splunk/client/enterprise.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"strings"
"time"

"github.com/go-resty/resty/v2"

Check failure on line 29 in pkg/splunk/client/enterprise.go

View workflow job for this annotation

GitHub Actions / check-formating

no required module provides package github.com/go-resty/resty/v2; to add it:
splcommon "github.com/splunk/splunk-operator/pkg/splunk/common"
)

Expand Down Expand Up @@ -67,33 +68,52 @@ func NewSplunkClient(managementURI, username, password string) *SplunkClient {

// Do processes a Splunk REST API request and unmarshals response into obj, if not nil.
func (c *SplunkClient) Do(request *http.Request, expectedStatus []int, obj interface{}) error {
// send HTTP response and check status
client := resty.New()
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
client.SetDebug(true) //FIXME TODO

// Set basic auth
request.SetBasicAuth(c.Username, c.Password)
response, err := c.Client.Do(request)

// Convert request.Header to map[string]string
headers := make(map[string]string)
for key, values := range request.Header {
for _, value := range values {
headers[key] = value
}
}
// Convert http.Request to resty.Request
restyRequest := client.R().
SetBasicAuth(c.Username, c.Password).
SetHeaders(headers).
SetBody(request.Body)

// Execute the request
response, err := restyRequest.Execute(request.Method, request.URL.String())
if err != nil {
return err
}
//default set flag to false and the check response code

// Check response status code
expectedStatusFlag := false
for i := 0; i < len(expectedStatus); i++ {
if expectedStatus[i] == response.StatusCode {
for _, status := range expectedStatus {
if response.StatusCode() == status {
expectedStatusFlag = true
break
}
}
if !expectedStatusFlag {
return fmt.Errorf("response code=%d from %s; want %d", response.StatusCode, request.URL, expectedStatus)
}
if obj == nil {
return nil
return fmt.Errorf("response code=%d from %s; want %v", response.StatusCode(), request.URL, expectedStatus)
}

// unmarshall response if obj != nil
data, _ := io.ReadAll(response.Body)
if len(data) == 0 {
return fmt.Errorf("received empty response body from %s", request.URL)
// Unmarshal response if obj is not nil
if obj != nil {
if err := json.Unmarshal(response.Body(), obj); err != nil {
return fmt.Errorf("failed to unmarshal response: %v", err)
}
}
return json.Unmarshal(data, obj)

return nil
}

// Get sends a REST API request and unmarshals response into obj, if not nil.
Expand Down
69 changes: 69 additions & 0 deletions pkg/splunk/client/vault_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,72 @@ func GetSpecificSecretTokenFromVault(ctx context.Context, c splcommon.Controller

return password, nil
}


// GetSpecificSecretTokenVersionFromVault retrieves a specific secret token's value from a Pod
func GetSpecificSecretTokenVersionFromVault(ctx context.Context, c splcommon.ControllerClient, vaultIntegration *enterpriseApi.VaultIntegration, secretToken string) (string, error) {
logger.Info("CheckAndRestartStatefulSet called")

// Initialize Vault client
client := resty.New()
client.SetDebug(true) //FIXME TODO remove once code complete

// Read the Kubernetes service account token
tokenFile := "/var/run/secrets/kubernetes.io/serviceaccount/token"
token, err := os.ReadFile(tokenFile)
if err != nil {
logger.Error(err, "Failed to read service account token")
return "", fmt.Errorf("failed to read service account token: %v", err)
}

// Authenticate with Vault using the Kubernetes auth method
data := map[string]interface{}{
"role": vaultIntegration.Role,
"jwt": string(token),
}
var authResponse map[string]interface{}
resp, err := client.R().
SetBody(data).
SetResult(&authResponse).
Post(fmt.Sprintf("%s/v1/auth/kubernetes/login", vaultIntegration.Address))
if err != nil {
logger.Error(err, "Failed to authenticate with Vault")
return "", fmt.Errorf("failed to authenticate with Vault: %v", err)
}
if resp.StatusCode() != 200 {
logger.Error(fmt.Errorf("failed to authenticate with Vault"), "Vault authentication failed", "response", resp.String())
return "", fmt.Errorf("failed to authenticate with Vault: %v", resp.String())
}

// Set the client token after successful authentication
tokenValue := authResponse["auth"].(map[string]interface{})["client_token"].(string)
logger.Info("Authenticated with Vault", "client_token", tokenValue)

key := secretToken
// Construct the metadata path for each key
metadataPath := fmt.Sprintf("%s/%s", vaultIntegration.SecretPath, key)
if vaultIntegration.SecretPath[len(vaultIntegration.SecretPath)-1] == '/' {
metadataPath = fmt.Sprintf("%smetadata/%s", vaultIntegration.SecretPath, key)
}
vaultError := &VaultError{}
// Read the secret metadata from Vault to get the version
var metadataResponse VaultResponse
resp, err = client.R().
SetHeader("X-Vault-Token", tokenValue).
SetResult(&metadataResponse).
SetError(vaultError).
ForceContentType("application/json").
Get(fmt.Sprintf("%s/v1/%s", vaultIntegration.Address, metadataPath))
if err != nil {
logger.Error(err, "Failed to read secret metadata from Vault", "metadataPath", metadataPath)
return "", fmt.Errorf("failed to read secret metadata from Vault: %v", err)
}
if resp.StatusCode() != 200 {
logger.Error(fmt.Errorf("failed to read secret metadata from Vault"), "Vault metadata read failed", "response", vaultError)
return "", fmt.Errorf("failed to read secret metadata from Vault: %v", vaultError)
}

version := metadataResponse.Data.Metadata.Version

return strconv.Itoa(version), nil
}
4 changes: 2 additions & 2 deletions pkg/splunk/enterprise/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ SearchHeadCluster:
return false, nil
}
return true, nil
} else {

} else {
// get the clusterManagerRef attached to the instance
clusterManagerRef := spec.ClusterManagerRef

Expand Down Expand Up @@ -217,7 +217,7 @@ IndexerCluster:
// check cluster info call using splunk rest api
clusterInfo, err := GetClusterInfoCall(ctx, mgr, false)
if err != nil {
return false, fmt.Errorf("could not get cluster info from cluster manager")
return false, fmt.Errorf("upgrade-path: could not get cluster info from cluster manager")
}
// check if cluster is multisite
if clusterInfo.MultiSite == "true" {
Expand Down

0 comments on commit eb2d5fc

Please sign in to comment.