mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 15:27:27 +00:00
Add auto install pre commit
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
|
||||||
|
# MANAGED BY INFISICAL CLI (Do not modify): START
|
||||||
|
infisicalScanEnabled=$(git config --bool hooks.infisical-scan)
|
||||||
|
|
||||||
|
if [ "$infisicalScanEnabled" != "false" ]; then
|
||||||
|
infisical scan git-changes -v --staged
|
||||||
|
exitCode=$?
|
||||||
|
if [ $exitCode -eq 1 ]; then
|
||||||
|
echo "Commit blocked: Infisical scan has uncovered secrets in your git commit"
|
||||||
|
echo "To disable the Infisical scan precommit hook run the following command:"
|
||||||
|
echo ""
|
||||||
|
echo " git config hooks.infisical-scan false"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Warning: infisical scan precommit disabled'
|
||||||
|
fi
|
||||||
|
# MANAGED BY INFISICAL CLI (Do not modify): END
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# MANAGED BY INFISICAL CLI (Do not modify): START
|
||||||
|
infisicalScanEnabled=$(git config --bool hooks.infisical-scan)
|
||||||
|
|
||||||
|
if [ "$infisicalScanEnabled" != "false" ]; then
|
||||||
|
infisical scan git-changes -v --staged
|
||||||
|
exitCode=$?
|
||||||
|
if [ $exitCode -eq 1 ]; then
|
||||||
|
echo "Commit blocked: Infisical scan has uncovered secrets in your git commit"
|
||||||
|
echo "To disable the Infisical scan precommit hook run the following command:"
|
||||||
|
echo ""
|
||||||
|
echo " git config hooks.infisical-scan false"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Warning: infisical scan precommit disabled'
|
||||||
|
fi
|
||||||
|
# MANAGED BY INFISICAL CLI (Do not modify): END
|
||||||
@@ -23,7 +23,11 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -32,6 +36,7 @@ import (
|
|||||||
"github.com/Infisical/infisical-merge/detect"
|
"github.com/Infisical/infisical-merge/detect"
|
||||||
"github.com/Infisical/infisical-merge/packages/util"
|
"github.com/Infisical/infisical-merge/packages/util"
|
||||||
"github.com/Infisical/infisical-merge/report"
|
"github.com/Infisical/infisical-merge/report"
|
||||||
|
"github.com/manifoldco/promptui"
|
||||||
"github.com/posthog/posthog-go"
|
"github.com/posthog/posthog-go"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -45,6 +50,17 @@ order of precedence:
|
|||||||
3. (--source/-s)/.infisical-scan.toml
|
3. (--source/-s)/.infisical-scan.toml
|
||||||
If none of the three options are used, then Infisical will use the default scan config`
|
If none of the three options are used, then Infisical will use the default scan config`
|
||||||
|
|
||||||
|
//go:embed pre-commit-script/pre-commit.sh
|
||||||
|
var preCommitTemplate []byte
|
||||||
|
|
||||||
|
//go:embed pre-commit-script/pre-commit-without-bang.sh
|
||||||
|
var preCommitTemplateAppend []byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultHooksPath = ".git/hooks/"
|
||||||
|
preCommitFile = "pre-commit"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// scan flag for only scan command
|
// scan flag for only scan command
|
||||||
scanCmd.Flags().String("log-opts", "", "git log options")
|
scanCmd.Flags().String("log-opts", "", "git log options")
|
||||||
@@ -77,6 +93,9 @@ func init() {
|
|||||||
// add flags to main
|
// add flags to main
|
||||||
scanCmd.AddCommand(scanGitChangesCmd)
|
scanCmd.AddCommand(scanGitChangesCmd)
|
||||||
rootCmd.AddCommand(scanCmd)
|
rootCmd.AddCommand(scanCmd)
|
||||||
|
|
||||||
|
installCmd.Flags().Bool("pre-commit-hook", false, "installs pre commit hook for Git repository")
|
||||||
|
scanCmd.AddCommand(installCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initScanConfig(cmd *cobra.Command) {
|
func initScanConfig(cmd *cobra.Command) {
|
||||||
@@ -132,6 +151,50 @@ func initScanConfig(cmd *cobra.Command) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var installCmd = &cobra.Command{
|
||||||
|
Use: "install",
|
||||||
|
Short: "Install scanning scripts and tools. Use --help flag to see all options",
|
||||||
|
Args: cobra.ExactArgs(0),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
installPrecommit := cmd.Flags().Changed("pre-commit-hook")
|
||||||
|
if installPrecommit {
|
||||||
|
hooksPath, err := getHooksPath()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if hooksPath != ".git/hooks" {
|
||||||
|
defaultHookOverride, err := overrideDefaultHooksPath(hooksPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if defaultHookOverride {
|
||||||
|
ConfigureGitHooksPath()
|
||||||
|
|
||||||
|
log.Info().Msgf("To switch back previous githooks manager run: git config core.hooksPath %s\n", hooksPath)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
log.Warn().Msgf("To automatically configure this hook, you need to switch the path of the Hooks. Alternatively, you can manually configure this hook by setting your pre-commit script to run command [infisical scan git-changes -v --staged].\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = createOrUpdatePreCommitFile(hooksPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().Msgf("Pre-commit hook successfully added. Infisical scan should now run on each commit you make\n")
|
||||||
|
|
||||||
|
Telemetry.CaptureEvent("cli-command:install --pre-commit-hook", posthog.NewProperties().Set("version", util.CLI_VERSION))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
var scanCmd = &cobra.Command{
|
var scanCmd = &cobra.Command{
|
||||||
Use: "scan",
|
Use: "scan",
|
||||||
Short: "Scan for leaked secrets in git history, directories, and files",
|
Short: "Scan for leaked secrets in git history, directories, and files",
|
||||||
@@ -417,3 +480,103 @@ func FormatDuration(d time.Duration) string {
|
|||||||
}
|
}
|
||||||
return d.Round(scale / 100).String()
|
return d.Round(scale / 100).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func overrideDefaultHooksPath(managedHook string) (bool, error) {
|
||||||
|
YES := "Yes"
|
||||||
|
NO := "No"
|
||||||
|
|
||||||
|
options := []string{YES, NO}
|
||||||
|
optionsPrompt := promptui.Select{
|
||||||
|
Label: fmt.Sprintf("Your hooks path is set to [%s] but needs to be [.git/hooks] for automatic configuration. Would you like to switch? ", managedHook),
|
||||||
|
Items: options,
|
||||||
|
Size: 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, selectedOption, err := optionsPrompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectedOption == YES, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfigureGitHooksPath() {
|
||||||
|
cmd := exec.Command("git", "config", "core.hooksPath", ".git/hooks")
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Fatal().Msgf("Failed to configure git hooks path: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGitRoot returns the root directory of the current Git repository.
|
||||||
|
func GetGitRoot() (string, error) {
|
||||||
|
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
|
||||||
|
output, err := cmd.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to get git root directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gitRoot := strings.TrimSpace(string(output)) // Remove any trailing newline
|
||||||
|
return gitRoot, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHooksPath() (string, error) {
|
||||||
|
out, err := exec.Command("git", "config", "core.hooksPath").Output()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to get Git hooks path: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hooksPath := strings.TrimSpace(string(out))
|
||||||
|
return hooksPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createOrUpdatePreCommitFile(hooksPath string) error {
|
||||||
|
// File doesn't exist, create a new one
|
||||||
|
rootGitRepoPath, err := GetGitRoot()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := fmt.Sprintf("%s/%s/%s", rootGitRepoPath, hooksPath, preCommitFile)
|
||||||
|
|
||||||
|
_, err = os.Stat(filePath)
|
||||||
|
if err == nil {
|
||||||
|
// File already exists, check if it contains the managed comments
|
||||||
|
content, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read pre-commit file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(string(content), "# MANAGED BY INFISICAL CLI (Do not modify): START") &&
|
||||||
|
strings.Contains(string(content), "# MANAGED BY INFISICAL CLI (Do not modify): END") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// File already exists, append the template content
|
||||||
|
file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open pre-commit file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
_, err = file.Write(preCommitTemplateAppend)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to append to pre-commit file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if os.IsNotExist(err) {
|
||||||
|
err = os.WriteFile(filePath, preCommitTemplate, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create pre-commit file: %s", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Error occurred while checking file status
|
||||||
|
return fmt.Errorf("failed to check pre-commit file status: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user