mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-09 15:38:03 -05:00
feat: cli-folders-cmd
This commit is contained in:
@@ -260,6 +260,82 @@ func CallGetSecretsV3(httpClient *resty.Client, request GetEncryptedSecretsV3Req
|
||||
return secretsResponse, nil
|
||||
}
|
||||
|
||||
func CallGetFoldersV1(httpClient *resty.Client, request GetFoldersV1Request) (GetFoldersV1Response, error) {
|
||||
var foldersResponse GetFoldersV1Response
|
||||
httpRequest := httpClient.
|
||||
R().
|
||||
SetResult(&foldersResponse).
|
||||
SetHeader("User-Agent", USER_AGENT).
|
||||
SetQueryParam("environment", request.Environment).
|
||||
SetQueryParam("workspaceId", request.WorkspaceId).
|
||||
SetQueryParam("directory", request.FoldersPath)
|
||||
|
||||
response, err := httpRequest.Get(fmt.Sprintf("%v/v1/folders", config.INFISICAL_URL))
|
||||
|
||||
if err != nil {
|
||||
return GetFoldersV1Response{}, fmt.Errorf("CallGetFoldersV1: Unable to complete api request [err=%s]", err)
|
||||
}
|
||||
|
||||
if response.IsError() {
|
||||
return GetFoldersV1Response{}, fmt.Errorf("CallGetFoldersV1: Unsuccessful response. Please make sure your secret path, workspace and environment name are all correct [response=%s]", response)
|
||||
}
|
||||
|
||||
return foldersResponse, nil
|
||||
}
|
||||
|
||||
func CallCreateFolderV1(httpClient *resty.Client, request CreateFolderV1Request) (CreateFolderV1Response, error) {
|
||||
var folderResponse CreateFolderV1Response
|
||||
httpRequest := httpClient.
|
||||
R().
|
||||
SetResult(&folderResponse).
|
||||
SetHeader("User-Agent", USER_AGENT).
|
||||
SetBody(request)
|
||||
|
||||
response, err := httpRequest.Post(fmt.Sprintf("%v/v1/folders", config.INFISICAL_URL))
|
||||
if err != nil {
|
||||
return CreateFolderV1Response{}, fmt.Errorf("CallCreateFolderV1: Unable to complete api request [err=%s]", err)
|
||||
}
|
||||
|
||||
if response.IsError() {
|
||||
return CreateFolderV1Response{}, fmt.Errorf("CallCreateFolderV1: Unsuccessful response. Please make sure your secret path, workspace and environment name are all correct [response=%s]", response)
|
||||
}
|
||||
|
||||
return folderResponse, nil
|
||||
}
|
||||
|
||||
func CallDeleteFolderV1(httpClient *resty.Client, request DeleteFolderV1Request) (DeleteFolderV1Response, error) {
|
||||
var folderResponse DeleteFolderV1Response
|
||||
|
||||
type deleteFolderRequest struct {
|
||||
WorkspaceId string `json:"workspaceId"`
|
||||
Environment string `json:"environment"`
|
||||
Directory string `json:"folderPath"`
|
||||
}
|
||||
|
||||
body := deleteFolderRequest{
|
||||
WorkspaceId: request.WorkspaceId,
|
||||
Environment: request.Environment,
|
||||
Directory: request.Directory,
|
||||
}
|
||||
|
||||
httpRequest := httpClient.
|
||||
R().
|
||||
SetResult(&folderResponse).
|
||||
SetHeader("User-Agent", USER_AGENT).
|
||||
SetBody(body)
|
||||
|
||||
response, err := httpRequest.Delete(fmt.Sprintf("%v/v1/folders/%v", config.INFISICAL_URL, request.FolderName))
|
||||
if err != nil {
|
||||
return DeleteFolderV1Response{}, fmt.Errorf("CallDeleteFolderV1: Unable to complete api request [err=%s]", err)
|
||||
}
|
||||
|
||||
if response.IsError() {
|
||||
return DeleteFolderV1Response{}, fmt.Errorf("CallDeleteFolderV1: Unsuccessful response. Please make sure your secret path, workspace and environment name are all correct [response=%s]", response)
|
||||
}
|
||||
|
||||
return folderResponse, nil
|
||||
}
|
||||
|
||||
func CallCreateSecretsV3(httpClient *resty.Client, request CreateSecretV3Request) error {
|
||||
var secretsResponse GetEncryptedSecretsV3Response
|
||||
response, err := httpClient.
|
||||
|
||||
@@ -278,6 +278,47 @@ type GetEncryptedSecretsV3Request struct {
|
||||
IncludeImport bool `json:"include_imports"`
|
||||
}
|
||||
|
||||
type GetFoldersV1Request struct {
|
||||
Environment string `json:"environment"`
|
||||
WorkspaceId string `json:"workspaceId"`
|
||||
FoldersPath string `json:"foldersPath"`
|
||||
}
|
||||
|
||||
type GetFoldersV1Response struct {
|
||||
Folders []struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"folders"`
|
||||
}
|
||||
|
||||
type CreateFolderV1Request struct {
|
||||
FolderName string `json:"folderName"`
|
||||
WorkspaceId string `json:"workspaceId"`
|
||||
Environment string `json:"environment"`
|
||||
Directory string `json:"directory"`
|
||||
}
|
||||
|
||||
type CreateFolderV1Response struct {
|
||||
Folder struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"folder"`
|
||||
}
|
||||
|
||||
type DeleteFolderV1Request struct {
|
||||
FolderName string `json:"folderName"`
|
||||
WorkspaceId string `json:"workspaceId"`
|
||||
Environment string `json:"environment"`
|
||||
Directory string `json:"directory"`
|
||||
}
|
||||
|
||||
type DeleteFolderV1Response struct {
|
||||
Folders []struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"folders"`
|
||||
}
|
||||
|
||||
type EncryptedSecretV3 struct {
|
||||
ID string `json:"_id"`
|
||||
Version int `json:"version"`
|
||||
|
||||
191
cli/packages/cmd/folder.go
Normal file
191
cli/packages/cmd/folder.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
"github.com/Infisical/infisical-merge/packages/util"
|
||||
"github.com/Infisical/infisical-merge/packages/visualize"
|
||||
"github.com/posthog/posthog-go"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var folderCmd = &cobra.Command{
|
||||
Use: "folders",
|
||||
Short: "Create, delete, and list folders",
|
||||
DisableFlagsInUseLine: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
var getCmd = &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get folders in a directory",
|
||||
DisableFlagsInUseLine: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
environmentName, _ := cmd.Flags().GetString("env")
|
||||
if !cmd.Flags().Changed("env") {
|
||||
environmentFromWorkspace := util.GetEnvFromWorkspaceFile()
|
||||
if environmentFromWorkspace != "" {
|
||||
environmentName = environmentFromWorkspace
|
||||
}
|
||||
}
|
||||
|
||||
infisicalToken, err := cmd.Flags().GetString("token")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
foldersPath, err := cmd.Flags().GetString("path")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
folders, err := util.GetAllFolders(models.GetAllFoldersParameters{Environment: environmentName, InfisicalToken: infisicalToken, FoldersPath: foldersPath})
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to get folders")
|
||||
}
|
||||
|
||||
visualize.PrintAllFoldersDetails(folders)
|
||||
Telemetry.CaptureEvent("cli-command:folders get", posthog.NewProperties().Set("folderCount", len(folders)).Set("version", util.CLI_VERSION))
|
||||
},
|
||||
}
|
||||
|
||||
var createCmd = &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a folder",
|
||||
DisableFlagsInUseLine: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
util.RequireLocalWorkspaceFile()
|
||||
environmentName, _ := cmd.Flags().GetString("env")
|
||||
if !cmd.Flags().Changed("env") {
|
||||
environmentFromWorkspace := util.GetEnvFromWorkspaceFile()
|
||||
if environmentFromWorkspace != "" {
|
||||
environmentName = environmentFromWorkspace
|
||||
}
|
||||
}
|
||||
|
||||
infisicalToken, err := cmd.Flags().GetString("token")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
folderPath, err := cmd.Flags().GetString("path")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
folderName, err := cmd.Flags().GetString("name")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse name flag")
|
||||
}
|
||||
|
||||
if folderName == "" {
|
||||
util.HandleError(fmt.Errorf("Invalid folder name"), "Folder name cannot be empty")
|
||||
}
|
||||
|
||||
workspaceFile, err := util.GetWorkSpaceFromFile()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to get workspace file")
|
||||
}
|
||||
|
||||
params := models.CreateFolderParameters{
|
||||
FolderName: folderName,
|
||||
WorkspaceId: workspaceFile.WorkspaceId,
|
||||
Environment: environmentName,
|
||||
FolderPath: folderPath,
|
||||
InfisicalToken: infisicalToken}
|
||||
|
||||
folder, err := util.CreateFolder(params)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to create folder")
|
||||
}
|
||||
|
||||
folders := []models.SingleFolder{folder}
|
||||
visualize.PrintAllFoldersDetails(folders)
|
||||
Telemetry.CaptureEvent("cli-command:folders create", posthog.NewProperties().Set("version", util.CLI_VERSION))
|
||||
},
|
||||
}
|
||||
|
||||
var deleteCmd = &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete a folder",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
util.RequireLocalWorkspaceFile()
|
||||
|
||||
environmentName, _ := cmd.Flags().GetString("env")
|
||||
if !cmd.Flags().Changed("env") {
|
||||
environmentFromWorkspace := util.GetEnvFromWorkspaceFile()
|
||||
if environmentFromWorkspace != "" {
|
||||
environmentName = environmentFromWorkspace
|
||||
}
|
||||
}
|
||||
|
||||
infisicalToken, err := cmd.Flags().GetString("token")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
folderPath, err := cmd.Flags().GetString("path")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
folderName, err := cmd.Flags().GetString("name")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse name flag")
|
||||
}
|
||||
|
||||
if folderName == "" {
|
||||
util.HandleError(fmt.Errorf("Invalid folder name"), "Folder name cannot be empty")
|
||||
}
|
||||
|
||||
workspaceFile, err := util.GetWorkSpaceFromFile()
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to get workspace file")
|
||||
}
|
||||
|
||||
params := models.DeleteFolderParameters{
|
||||
FolderName: folderName,
|
||||
WorkspaceId: workspaceFile.WorkspaceId,
|
||||
Environment: environmentName,
|
||||
FolderPath: folderPath,
|
||||
InfisicalToken: infisicalToken,
|
||||
}
|
||||
|
||||
folders, err := util.DeleteFolder(params)
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to delete folder")
|
||||
}
|
||||
|
||||
visualize.PrintAllFoldersDetails(folders)
|
||||
Telemetry.CaptureEvent("cli-command:folders delete", posthog.NewProperties().Set("version", util.CLI_VERSION))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
folderCmd.PersistentFlags().String("env", "dev", "Used to select the environment name on which actions should be taken on")
|
||||
|
||||
// Add getCmd, createCmd and deleteCmd flags here
|
||||
getCmd.Flags().StringP("path", "p", "/", "Path to the directory whose folders will be fetched")
|
||||
getCmd.Flags().StringP("token", "t", "", "Fetch folders using the infisical token")
|
||||
folderCmd.AddCommand(getCmd)
|
||||
|
||||
// Add createCmd flags here
|
||||
createCmd.Flags().StringP("path", "p", "/", "Path to the directory where the folder will be created")
|
||||
createCmd.Flags().StringP("token", "t", "", "Create folder using the infisical token")
|
||||
createCmd.Flags().StringP("name", "n", "", "Name of the folder to be created")
|
||||
folderCmd.AddCommand(createCmd)
|
||||
|
||||
// Add deleteCmd flags here
|
||||
deleteCmd.Flags().StringP("path", "p", "/", "Path to the directory where the folder will be deleted")
|
||||
deleteCmd.Flags().StringP("token", "t", "", "Delete folder using the infisical token")
|
||||
deleteCmd.Flags().StringP("name", "n", "", "Name of the folder to be deleted")
|
||||
folderCmd.AddCommand(deleteCmd)
|
||||
|
||||
rootCmd.AddCommand(folderCmd)
|
||||
|
||||
}
|
||||
@@ -34,6 +34,11 @@ type SingleEnvironmentVariable struct {
|
||||
Comment string `json:"comment"`
|
||||
}
|
||||
|
||||
type SingleFolder struct {
|
||||
ID string `json:"_id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Workspace struct {
|
||||
ID string `json:"_id"`
|
||||
Name string `json:"name"`
|
||||
@@ -63,3 +68,26 @@ type GetAllSecretsParameters struct {
|
||||
SecretsPath string
|
||||
IncludeImport bool
|
||||
}
|
||||
|
||||
type GetAllFoldersParameters struct {
|
||||
WorkspaceId string
|
||||
Environment string
|
||||
FoldersPath string
|
||||
InfisicalToken string
|
||||
}
|
||||
|
||||
type CreateFolderParameters struct {
|
||||
FolderName string
|
||||
WorkspaceId string
|
||||
Environment string
|
||||
FolderPath string
|
||||
InfisicalToken string
|
||||
}
|
||||
|
||||
type DeleteFolderParameters struct {
|
||||
FolderName string
|
||||
WorkspaceId string
|
||||
Environment string
|
||||
FolderPath string
|
||||
InfisicalToken string
|
||||
}
|
||||
|
||||
217
cli/packages/util/folders.go
Normal file
217
cli/packages/util/folders.go
Normal file
@@ -0,0 +1,217 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/api"
|
||||
"github.com/Infisical/infisical-merge/packages/models"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func GetAllFolders(params models.GetAllFoldersParameters) ([]models.SingleFolder, error) {
|
||||
|
||||
if params.InfisicalToken == "" {
|
||||
params.InfisicalToken = os.Getenv(INFISICAL_TOKEN_NAME)
|
||||
}
|
||||
|
||||
isConnected := CheckIsConnectedToInternet()
|
||||
var foldersToReturn []models.SingleFolder
|
||||
var folderErr error
|
||||
if params.InfisicalToken == "" {
|
||||
if isConnected {
|
||||
log.Debug().Msg("GetAllFolders: Connected to internet, checking logged in creds")
|
||||
RequireLocalWorkspaceFile()
|
||||
RequireLogin()
|
||||
}
|
||||
|
||||
log.Debug().Msg("GetAllEnvironmentVariables: Trying to fetch secrets using logged in details")
|
||||
|
||||
loggedInUserDetails, err := GetCurrentLoggedInUserDetails()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if loggedInUserDetails.LoginExpired {
|
||||
PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
|
||||
}
|
||||
|
||||
workspaceFile, err := GetWorkSpaceFromFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if params.WorkspaceId != "" {
|
||||
workspaceFile.WorkspaceId = params.WorkspaceId
|
||||
}
|
||||
|
||||
folders, err := GetFoldersViaJTW(loggedInUserDetails.UserCredentials.JTWToken, workspaceFile.WorkspaceId, params.Environment, params.FoldersPath)
|
||||
folderErr = err
|
||||
foldersToReturn = folders
|
||||
} else {
|
||||
// get folders via service token
|
||||
folders, err := GetFoldersViaServiceToken(params.InfisicalToken, params.WorkspaceId, params.Environment, params.FoldersPath)
|
||||
folderErr = err
|
||||
foldersToReturn = folders
|
||||
}
|
||||
return foldersToReturn, folderErr
|
||||
}
|
||||
|
||||
func GetFoldersViaJTW(JTWToken string, workspaceId string, environmentName string, foldersPath string) ([]models.SingleFolder, error) {
|
||||
// set up resty client
|
||||
httpClient := resty.New()
|
||||
httpClient.SetAuthToken(JTWToken).
|
||||
SetHeader("Accept", "application/json")
|
||||
|
||||
getFoldersRequest := api.GetFoldersV1Request{
|
||||
WorkspaceId: workspaceId,
|
||||
Environment: environmentName,
|
||||
FoldersPath: foldersPath,
|
||||
}
|
||||
|
||||
apiResponse, err := api.CallGetFoldersV1(httpClient, getFoldersRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var folders []models.SingleFolder
|
||||
|
||||
for _, folder := range apiResponse.Folders {
|
||||
folders = append(folders, models.SingleFolder{
|
||||
Name: folder.Name,
|
||||
ID: folder.ID,
|
||||
})
|
||||
}
|
||||
|
||||
return folders, nil
|
||||
}
|
||||
|
||||
func GetFoldersViaServiceToken(fullServiceToken string, workspaceId string, environmentName string, foldersPath string) ([]models.SingleFolder, error) {
|
||||
serviceTokenParts := strings.SplitN(fullServiceToken, ".", 4)
|
||||
if len(serviceTokenParts) < 4 {
|
||||
return nil, fmt.Errorf("invalid service token entered. Please double check your service token and try again")
|
||||
}
|
||||
|
||||
serviceToken := fmt.Sprintf("%v.%v.%v", serviceTokenParts[0], serviceTokenParts[1], serviceTokenParts[2])
|
||||
|
||||
httpClient := resty.New()
|
||||
|
||||
httpClient.SetAuthToken(serviceToken).
|
||||
SetHeader("Accept", "application/json")
|
||||
|
||||
serviceTokenDetails, err := api.CallGetServiceTokenDetailsV2(httpClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get service token details. [err=%v]", err)
|
||||
}
|
||||
|
||||
// if multiple scopes are there then user needs to specify which environment and folder path
|
||||
if environmentName == "" {
|
||||
if len(serviceTokenDetails.Scopes) != 1 {
|
||||
return nil, fmt.Errorf("you need to provide the --env for multiple environment scoped token")
|
||||
} else {
|
||||
environmentName = serviceTokenDetails.Scopes[0].Environment
|
||||
}
|
||||
}
|
||||
|
||||
getFoldersRequest := api.GetFoldersV1Request{
|
||||
WorkspaceId: serviceTokenDetails.Workspace,
|
||||
Environment: environmentName,
|
||||
FoldersPath: foldersPath,
|
||||
}
|
||||
|
||||
apiResponse, err := api.CallGetFoldersV1(httpClient, getFoldersRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get folders. [err=%v]", err)
|
||||
}
|
||||
|
||||
var folders []models.SingleFolder
|
||||
|
||||
for _, folder := range apiResponse.Folders {
|
||||
folders = append(folders, models.SingleFolder{
|
||||
Name: folder.Name,
|
||||
ID: folder.ID,
|
||||
})
|
||||
}
|
||||
|
||||
return folders, nil
|
||||
}
|
||||
|
||||
// CreateFolder creates a folder in Infisical
|
||||
func CreateFolder(params models.CreateFolderParameters) (models.SingleFolder, error) {
|
||||
loggedInUserDetails, err := GetCurrentLoggedInUserDetails()
|
||||
if err != nil {
|
||||
return models.SingleFolder{}, err
|
||||
}
|
||||
|
||||
if loggedInUserDetails.LoginExpired {
|
||||
PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
|
||||
}
|
||||
|
||||
// set up resty client
|
||||
httpClient := resty.New()
|
||||
httpClient.
|
||||
SetAuthToken(loggedInUserDetails.UserCredentials.JTWToken).
|
||||
SetHeader("Accept", "application/json").
|
||||
SetHeader("Content-Type", "application/json")
|
||||
|
||||
createFolderRequest := api.CreateFolderV1Request{
|
||||
WorkspaceId: params.WorkspaceId,
|
||||
Environment: params.Environment,
|
||||
FolderName: params.FolderName,
|
||||
Directory: params.FolderPath,
|
||||
}
|
||||
|
||||
apiResponse, err := api.CallCreateFolderV1(httpClient, createFolderRequest)
|
||||
if err != nil {
|
||||
return models.SingleFolder{}, err
|
||||
}
|
||||
|
||||
folder := apiResponse.Folder
|
||||
|
||||
return models.SingleFolder{
|
||||
Name: folder.Name,
|
||||
ID: folder.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func DeleteFolder(params models.DeleteFolderParameters) ([]models.SingleFolder, error) {
|
||||
loggedInUserDetails, err := GetCurrentLoggedInUserDetails()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if loggedInUserDetails.LoginExpired {
|
||||
PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
|
||||
}
|
||||
|
||||
// set up resty client
|
||||
httpClient := resty.New()
|
||||
httpClient.
|
||||
SetAuthToken(loggedInUserDetails.UserCredentials.JTWToken).
|
||||
SetHeader("Accept", "application/json").
|
||||
SetHeader("Content-Type", "application/json")
|
||||
|
||||
deleteFolderRequest := api.DeleteFolderV1Request{
|
||||
WorkspaceId: params.WorkspaceId,
|
||||
Environment: params.Environment,
|
||||
FolderName: params.FolderName,
|
||||
}
|
||||
|
||||
apiResponse, err := api.CallDeleteFolderV1(httpClient, deleteFolderRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var folders []models.SingleFolder
|
||||
|
||||
for _, folder := range apiResponse.Folders {
|
||||
folders = append(folders, models.SingleFolder{
|
||||
Name: folder.Name,
|
||||
ID: folder.ID,
|
||||
})
|
||||
}
|
||||
|
||||
return folders, nil
|
||||
}
|
||||
14
cli/packages/visualize/folders.go
Normal file
14
cli/packages/visualize/folders.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package visualize
|
||||
|
||||
import "github.com/Infisical/infisical-merge/packages/models"
|
||||
|
||||
func PrintAllFoldersDetails(folders []models.SingleFolder) {
|
||||
rows := [][3]string{}
|
||||
for _, folder := range folders {
|
||||
rows = append(rows, [...]string{folder.ID, folder.Name, ""})
|
||||
}
|
||||
|
||||
headers := [...]string{"FOLDER ID", "FOLDER NAME", "VERSION"}
|
||||
|
||||
Table(headers, rows)
|
||||
}
|
||||
Reference in New Issue
Block a user