diff --git a/cli/packages/api/api.go b/cli/packages/api/api.go index d438adb33..1b69b8f23 100644 --- a/cli/packages/api/api.go +++ b/cli/packages/api/api.go @@ -145,6 +145,25 @@ func CallLogin2V2(httpClient *resty.Client, request GetLoginTwoV2Request) (GetLo return loginTwoV2Response, nil } +func CallGetAllOrganizations(httpClient *resty.Client) (GetOrganizationsResponse, error) { + var orgResponse GetOrganizationsResponse + response, err := httpClient. + R(). + SetResult(&orgResponse). + SetHeader("User-Agent", USER_AGENT). + Get(fmt.Sprintf("%v/v1/organization", config.INFISICAL_URL)) + + if err != nil { + return GetOrganizationsResponse{}, err + } + + if response.IsError() { + return GetOrganizationsResponse{}, fmt.Errorf("CallGetAllOrganizations: Unsuccessful response: [response=%v]", response) + } + + return orgResponse, nil +} + func CallGetAllWorkSpacesUserBelongsTo(httpClient *resty.Client) (GetWorkSpacesResponse, error) { var workSpacesResponse GetWorkSpacesResponse response, err := httpClient. diff --git a/cli/packages/api/model.go b/cli/packages/api/model.go index 67ac97c25..586a23511 100644 --- a/cli/packages/api/model.go +++ b/cli/packages/api/model.go @@ -120,14 +120,21 @@ type PullSecretsByInfisicalTokenResponse struct { type GetWorkSpacesResponse struct { Workspaces []struct { - ID string `json:"_id"` - Name string `json:"name"` - Plan string `json:"plan,omitempty"` - V int `json:"__v"` - Organization string `json:"organization,omitempty"` + ID string `json:"_id"` + Name string `json:"name"` + Plan string `json:"plan,omitempty"` + V int `json:"__v"` + OrganizationId string `json:"orgId"` } `json:"workspaces"` } +type GetOrganizationsResponse struct { + Organizations []struct { + ID string `json:"id"` + Name string `json:"name"` + } `json:"organizations"` +} + type Secret struct { SecretKeyCiphertext string `json:"secretKeyCiphertext,omitempty"` SecretKeyIV string `json:"secretKeyIV,omitempty"` @@ -505,5 +512,5 @@ type GetRawSecretsV3Response struct { SecretComment string `json:"secretComment"` } `json:"secrets"` Imports []any `json:"imports"` - ETag string + ETag string } diff --git a/cli/packages/cmd/init.go b/cli/packages/cmd/init.go index 070074fa9..e47eb447e 100644 --- a/cli/packages/cmd/init.go +++ b/cli/packages/cmd/init.go @@ -5,7 +5,6 @@ package cmd import ( "encoding/json" - "fmt" "github.com/Infisical/infisical-merge/packages/api" "github.com/Infisical/infisical-merge/packages/models" @@ -52,25 +51,19 @@ var initCmd = &cobra.Command{ httpClient := resty.New() httpClient.SetAuthToken(userCreds.UserCredentials.JTWToken) - workspaceResponse, err := api.CallGetAllWorkSpacesUserBelongsTo(httpClient) + + organizationResponse, err := api.CallGetAllOrganizations(httpClient) if err != nil { - util.HandleError(err, "Unable to pull projects that belong to you") + util.HandleError(err, "Unable to pull organizations that belong to you") } - workspaces := workspaceResponse.Workspaces - if len(workspaces) == 0 { - message := fmt.Sprintf("You don't have any projects created in Infisical. You must first create a project at %s", util.INFISICAL_TOKEN_NAME) - util.PrintErrorMessageAndExit(message) - } + organizations := organizationResponse.Organizations - var workspaceNames []string - for _, workspace := range workspaces { - workspaceNames = append(workspaceNames, workspace.Name) - } + organizationNames := util.GetOrganizationsNameList(organizationResponse) prompt := promptui.Select{ - Label: "Which of your Infisical projects would you like to connect this project to?", - Items: workspaceNames, + Label: "Which Infisical organization would you like to select a project from?", + Items: organizationNames, Size: 7, } @@ -79,7 +72,27 @@ var initCmd = &cobra.Command{ util.HandleError(err) } - err = writeWorkspaceFile(workspaces[index]) + selectedOrganization := organizations[index] + + workspaceResponse, err := api.CallGetAllWorkSpacesUserBelongsTo(httpClient) + if err != nil { + util.HandleError(err, "Unable to pull projects that belong to you") + } + + filteredWorkspaces, workspaceNames := util.GetWorkspacesInOrganization(workspaceResponse, selectedOrganization.ID) + + prompt = promptui.Select{ + Label: "Which of your Infisical projects would you like to connect this project to?", + Items: workspaceNames, + Size: 7, + } + + index, _, err = prompt.Run() + if err != nil { + util.HandleError(err) + } + + err = writeWorkspaceFile(filteredWorkspaces[index]) if err != nil { util.HandleError(err) } diff --git a/cli/packages/models/cli.go b/cli/packages/models/cli.go index 71033fe72..c3999f68b 100644 --- a/cli/packages/models/cli.go +++ b/cli/packages/models/cli.go @@ -45,11 +45,11 @@ type SingleFolder struct { } type Workspace struct { - ID string `json:"_id"` - Name string `json:"name"` - Plan string `json:"plan,omitempty"` - V int `json:"__v"` - Organization string `json:"organization,omitempty"` + ID string `json:"_id"` + Name string `json:"name"` + Plan string `json:"plan,omitempty"` + V int `json:"__v"` + OrganizationId string `json:"orgId"` } type WorkspaceConfigFile struct { diff --git a/cli/packages/util/init.go b/cli/packages/util/init.go new file mode 100644 index 000000000..33350f3b7 --- /dev/null +++ b/cli/packages/util/init.go @@ -0,0 +1,45 @@ +package util + +import ( + "fmt" + + "github.com/Infisical/infisical-merge/packages/api" + "github.com/Infisical/infisical-merge/packages/models" +) + +func GetOrganizationsNameList(organizationResponse api.GetOrganizationsResponse) []string { + organizations := organizationResponse.Organizations + + if len(organizations) == 0 { + message := fmt.Sprintf("You don't have any organization created in Infisical. You must first create a organization at %s", INFISICAL_DEFAULT_URL) + PrintErrorMessageAndExit(message) + } + + var organizationNames []string + for _, workspace := range organizations { + organizationNames = append(organizationNames, workspace.Name) + } + + return organizationNames +} + +func GetWorkspacesInOrganization(workspaceResponse api.GetWorkSpacesResponse, orgId string) ([]models.Workspace, []string) { + workspaces := workspaceResponse.Workspaces + + var filteredWorkspaces []models.Workspace + var workspaceNames []string + + for _, workspace := range workspaces { + if workspace.OrganizationId == orgId { + filteredWorkspaces = append(filteredWorkspaces, workspace) + workspaceNames = append(workspaceNames, workspace.Name) + } + } + + if len(filteredWorkspaces) == 0 { + message := fmt.Sprintf("You don't have any projects created in Infisical organization. You must first create a project at %s", INFISICAL_DEFAULT_URL) + PrintErrorMessageAndExit(message) + } + + return filteredWorkspaces, workspaceNames +}