mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Make infisical ssh v2 work in non-interactive mode, allow reassignment of default ssh cas
This commit is contained in:
@@ -177,7 +177,6 @@ func issueCredentials(cmd *cobra.Command, args []string) {
|
||||
infisicalToken = token.Token
|
||||
} else {
|
||||
util.RequireLogin()
|
||||
util.RequireLocalWorkspaceFile()
|
||||
|
||||
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
|
||||
if err != nil {
|
||||
@@ -411,7 +410,6 @@ func signKey(cmd *cobra.Command, args []string) {
|
||||
infisicalToken = token.Token
|
||||
} else {
|
||||
util.RequireLogin()
|
||||
util.RequireLocalWorkspaceFile()
|
||||
|
||||
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
|
||||
if err != nil {
|
||||
@@ -610,25 +608,82 @@ func signKey(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
func sshConnect(cmd *cobra.Command, args []string) {
|
||||
util.RequireLogin()
|
||||
util.RequireLocalWorkspaceFile()
|
||||
|
||||
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
|
||||
token, err := util.GetInfisicalToken(cmd)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to authenticate")
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
var infisicalToken string
|
||||
|
||||
if loggedInUserDetails.LoginExpired {
|
||||
util.PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
|
||||
if token != nil && (token.Type == util.SERVICE_TOKEN_IDENTIFIER || token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER) {
|
||||
infisicalToken = token.Token
|
||||
} else {
|
||||
util.RequireLogin()
|
||||
|
||||
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to authenticate")
|
||||
}
|
||||
|
||||
if loggedInUserDetails.LoginExpired {
|
||||
util.PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
|
||||
}
|
||||
infisicalToken = loggedInUserDetails.UserCredentials.JTWToken
|
||||
}
|
||||
|
||||
infisicalToken := loggedInUserDetails.UserCredentials.JTWToken
|
||||
|
||||
writeHostCaToFile, err := cmd.Flags().GetBool("writeHostCaToFile")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse --writeHostCaToFile flag")
|
||||
}
|
||||
|
||||
outFilePath, err := cmd.Flags().GetString("outFilePath")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
hostname, _ := cmd.Flags().GetString("hostname")
|
||||
loginUser, _ := cmd.Flags().GetString("loginUser")
|
||||
|
||||
var outputDir, privateKeyPath, publicKeyPath, signedKeyPath string
|
||||
if outFilePath != "" {
|
||||
if strings.HasPrefix(outFilePath, "~") {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Failed to resolve home directory")
|
||||
}
|
||||
outFilePath = strings.Replace(outFilePath, "~", homeDir, 1)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(outFilePath, "-cert.pub") {
|
||||
signedKeyPath = outFilePath
|
||||
baseName := strings.TrimSuffix(filepath.Base(outFilePath), "-cert.pub")
|
||||
outputDir = filepath.Dir(outFilePath)
|
||||
privateKeyPath = filepath.Join(outputDir, baseName)
|
||||
publicKeyPath = filepath.Join(outputDir, baseName+".pub")
|
||||
} else {
|
||||
outputDir = outFilePath
|
||||
info, err := os.Stat(outputDir)
|
||||
if os.IsNotExist(err) {
|
||||
err = os.MkdirAll(outputDir, 0755)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Failed to create output directory")
|
||||
}
|
||||
} else if err != nil {
|
||||
util.HandleError(err, "Failed to access output directory")
|
||||
} else if !info.IsDir() {
|
||||
util.PrintErrorMessageAndExit("The provided --outFilePath is not a directory")
|
||||
}
|
||||
fileName := "id_ed25519"
|
||||
privateKeyPath = filepath.Join(outputDir, fileName)
|
||||
publicKeyPath = filepath.Join(outputDir, fileName+".pub")
|
||||
signedKeyPath = filepath.Join(outputDir, fileName+"-cert.pub")
|
||||
}
|
||||
|
||||
if privateKeyPath == "" || publicKeyPath == "" || signedKeyPath == "" {
|
||||
util.PrintErrorMessageAndExit("Failed to resolve file paths for writing credentials")
|
||||
}
|
||||
}
|
||||
|
||||
customHeaders, err := util.GetInfisicalCustomHeadersMap()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to get custom headers")
|
||||
@@ -651,43 +706,68 @@ func sshConnect(cmd *cobra.Command, args []string) {
|
||||
util.PrintErrorMessageAndExit("You do not have access to any SSH hosts")
|
||||
}
|
||||
|
||||
// Prompt to select host
|
||||
hostNames := make([]string, len(hosts))
|
||||
for i, h := range hosts {
|
||||
hostNames[i] = h.Hostname
|
||||
var selectedHost = hosts[0]
|
||||
if hostname != "" {
|
||||
foundHost := false
|
||||
for _, h := range hosts {
|
||||
if h.Hostname == hostname {
|
||||
selectedHost = h
|
||||
foundHost = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundHost {
|
||||
util.PrintErrorMessageAndExit("Specified --hostname not found or not accessible")
|
||||
}
|
||||
} else {
|
||||
hostNames := make([]string, len(hosts))
|
||||
for i, h := range hosts {
|
||||
hostNames[i] = h.Hostname
|
||||
}
|
||||
hostPrompt := promptui.Select{
|
||||
Label: "Select an SSH Host",
|
||||
Items: hostNames,
|
||||
Size: 10,
|
||||
}
|
||||
hostIdx, _, err := hostPrompt.Run()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Prompt failed")
|
||||
}
|
||||
selectedHost = hosts[hostIdx]
|
||||
}
|
||||
|
||||
hostPrompt := promptui.Select{
|
||||
Label: "Select an SSH Host",
|
||||
Items: hostNames,
|
||||
Size: 10,
|
||||
var selectedLoginUser string
|
||||
if loginUser != "" {
|
||||
foundLoginUser := false
|
||||
for _, m := range selectedHost.LoginMappings {
|
||||
if m.LoginUser == loginUser {
|
||||
selectedLoginUser = loginUser
|
||||
foundLoginUser = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundLoginUser {
|
||||
util.PrintErrorMessageAndExit("Specified --loginUser not valid for selected host")
|
||||
}
|
||||
} else {
|
||||
if len(selectedHost.LoginMappings) == 0 {
|
||||
util.PrintErrorMessageAndExit("No login users available for selected host")
|
||||
}
|
||||
loginUsers := make([]string, len(selectedHost.LoginMappings))
|
||||
for i, m := range selectedHost.LoginMappings {
|
||||
loginUsers[i] = m.LoginUser
|
||||
}
|
||||
loginPrompt := promptui.Select{
|
||||
Label: "Select Login User",
|
||||
Items: loginUsers,
|
||||
Size: 5,
|
||||
}
|
||||
loginIdx, _, err := loginPrompt.Run()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Prompt failed")
|
||||
}
|
||||
selectedLoginUser = selectedHost.LoginMappings[loginIdx].LoginUser
|
||||
}
|
||||
hostIdx, _, err := hostPrompt.Run()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Prompt failed")
|
||||
}
|
||||
selectedHost := hosts[hostIdx]
|
||||
|
||||
// Prompt to select login user
|
||||
if len(selectedHost.LoginMappings) == 0 {
|
||||
util.PrintErrorMessageAndExit("No login users available for selected host")
|
||||
}
|
||||
|
||||
loginUsers := make([]string, len(selectedHost.LoginMappings))
|
||||
for i, m := range selectedHost.LoginMappings {
|
||||
loginUsers[i] = m.LoginUser
|
||||
}
|
||||
|
||||
loginPrompt := promptui.Select{
|
||||
Label: "Select Login User",
|
||||
Items: loginUsers,
|
||||
Size: 5,
|
||||
}
|
||||
loginIdx, _, err := loginPrompt.Run()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Prompt failed")
|
||||
}
|
||||
selectedLoginUser := selectedHost.LoginMappings[loginIdx].LoginUser
|
||||
|
||||
// Issue SSH creds for host
|
||||
creds, err := infisicalClient.Ssh().IssueSshHostUserCert(selectedHost.ID, infisicalSdk.IssueSshHostUserCertOptions{
|
||||
@@ -731,10 +811,27 @@ func sshConnect(cmd *cobra.Command, args []string) {
|
||||
util.HandleError(err, "Failed to write Host CA to known_hosts")
|
||||
}
|
||||
|
||||
fmt.Printf("📁 Wrote Host CA entry to %s\n", knownHostsPath)
|
||||
fmt.Printf("Successfully wrote Host CA entry to %s\n", knownHostsPath)
|
||||
}
|
||||
}
|
||||
|
||||
if outFilePath != "" {
|
||||
err = os.WriteFile(privateKeyPath, []byte(creds.PrivateKey), 0600)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Failed to write private key")
|
||||
}
|
||||
err = os.WriteFile(publicKeyPath, []byte(creds.PublicKey), 0644)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Failed to write public key")
|
||||
}
|
||||
err = os.WriteFile(signedKeyPath, []byte(creds.SignedKey), 0644)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Failed to write signed cert")
|
||||
}
|
||||
fmt.Printf("Successfully wrote credentials to %s, %s, and %s\n", privateKeyPath, publicKeyPath, signedKeyPath)
|
||||
return
|
||||
}
|
||||
|
||||
// Load credentials into SSH agent
|
||||
err = addCredentialsToAgent(creds.PrivateKey, creds.SignedKey)
|
||||
if err != nil {
|
||||
@@ -769,7 +866,6 @@ func sshAddHost(cmd *cobra.Command, args []string) {
|
||||
infisicalToken = token.Token
|
||||
} else {
|
||||
util.RequireLogin()
|
||||
util.RequireLocalWorkspaceFile()
|
||||
|
||||
loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails(true)
|
||||
if err != nil {
|
||||
@@ -1006,7 +1102,11 @@ func init() {
|
||||
sshIssueCredentialsCmd.Flags().Bool("addToAgent", false, "Whether to add issued SSH credentials to the SSH agent")
|
||||
sshCmd.AddCommand(sshIssueCredentialsCmd)
|
||||
|
||||
sshConnectCmd.Flags().String("token", "", "Use a machine identity access token")
|
||||
sshConnectCmd.Flags().Bool("writeHostCaToFile", true, "Write Host CA public key to ~/.ssh/known_hosts as a separate entry if doesn't already exist")
|
||||
sshConnectCmd.Flags().String("hostname", "", "Hostname of the SSH host to connect to")
|
||||
sshConnectCmd.Flags().String("loginUser", "", "Login user for the SSH connection")
|
||||
sshConnectCmd.Flags().String("outFilePath", "", "The path to write the SSH credentials to such as ~/.ssh, ./some_folder, ./some_folder/id_rsa-cert.pub. If not provided, the credentials will be added to the SSH agent and used to establish an interactive SSH connection")
|
||||
sshCmd.AddCommand(sshConnectCmd)
|
||||
|
||||
sshAddHostCmd.Flags().String("token", "", "Use a machine identity access token")
|
||||
|
||||
Reference in New Issue
Block a user