Skip to content

Commit 8b4f452

Browse files
committed
Feat: Add server push command to upload local project to server
1 parent cd4e7c3 commit 8b4f452

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

cli/cmd/enveil/server.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ var serverCmd = &cobra.Command{
1717
Short: "Manage server connection",
1818
}
1919

20+
var serverPushCmd = &cobra.Command{
21+
Use: "push",
22+
Short: "Push the current project and its variables to the server",
23+
RunE: runServerPush,
24+
}
25+
2026
var serverConnectCmd = &cobra.Command{
2127
Use: "connect <url>",
2228
Short: "Connect to an Enveil server",
@@ -45,6 +51,7 @@ var serverUseProjectCmd = &cobra.Command{
4551

4652
func init() {
4753
rootCmd.AddCommand(serverCmd)
54+
serverCmd.AddCommand(serverPushCmd)
4855
serverCmd.AddCommand(serverConnectCmd)
4956
serverCmd.AddCommand(serverDisconnectCmd)
5057
serverCmd.AddCommand(serverStatusCmd)
@@ -211,4 +218,87 @@ func runServerUseProject(cmd *cobra.Command, args []string) error {
211218
ui.Success("Directory associated with server project '%s'", name)
212219
ui.Info("Run 'enveil list' to see available variables")
213220
return nil
221+
}
222+
223+
func runServerPush(cmd *cobra.Command, args []string) error {
224+
cfg, err := config.Load()
225+
if err != nil {
226+
return err
227+
}
228+
229+
if !cfg.HasServer() {
230+
return fmt.Errorf("no server configured, run 'enveil server connect' first")
231+
}
232+
233+
if cfg.ActiveProject == "" {
234+
return fmt.Errorf("no active project, run 'enveil init' in your project directory first")
235+
}
236+
237+
// Abrir vault local
238+
masterKeyHex, err := promptAndDeriveKey(cfg)
239+
if err != nil {
240+
return err
241+
}
242+
243+
v, err := vault.Open(cfg.VaultPath, masterKeyHex)
244+
if err != nil {
245+
return err
246+
}
247+
defer v.Close()
248+
249+
// Obtener el proyecto local
250+
projectID, _, err := v.GetProjectByName(cfg.ActiveProject)
251+
if err != nil {
252+
return fmt.Errorf("error looking up project: %w", err)
253+
}
254+
if projectID == 0 {
255+
return fmt.Errorf("project '%s' not found in local vault", cfg.ActiveProject)
256+
}
257+
258+
client := serverclient.New(cfg.ServerURL, cfg.ServerAPIKey)
259+
260+
// Crear el proyecto en el servidor si no existe
261+
if err := client.EnsureProject(cfg.ActiveProject); err != nil {
262+
return fmt.Errorf("error creating project on server: %w", err)
263+
}
264+
265+
// Obtener todos los entornos locales
266+
envs, err := v.ListEnvironments(projectID)
267+
if err != nil {
268+
return fmt.Errorf("error listing environments: %w", err)
269+
}
270+
271+
totalVars := 0
272+
273+
for _, envName := range envs {
274+
// Crear el entorno en el servidor
275+
if err := client.EnsureEnvironment(cfg.ActiveProject, envName); err != nil {
276+
return fmt.Errorf("error creating environment '%s' on server: %w", envName, err)
277+
}
278+
279+
// Obtener el ID del entorno local
280+
envID, err := v.GetEnvironment(projectID, envName)
281+
if err != nil {
282+
return fmt.Errorf("error getting environment '%s': %w", envName, err)
283+
}
284+
285+
// Leer todas las variables del entorno
286+
vars, err := v.GetVariables(envID)
287+
if err != nil {
288+
return fmt.Errorf("error reading variables for '%s': %w", envName, err)
289+
}
290+
291+
// Subir cada variable al servidor
292+
for key, value := range vars {
293+
if err := client.SetVariable(cfg.ActiveProject, envName, key, value); err != nil {
294+
return fmt.Errorf("error pushing variable '%s': %w", key, err)
295+
}
296+
totalVars++
297+
}
298+
299+
ui.Info("Pushed environment '%s' (%d variables)", envName, len(vars))
300+
}
301+
302+
ui.Success("Project '%s' pushed to server (%d variables total)", cfg.ActiveProject, totalVars)
303+
return nil
214304
}

0 commit comments

Comments
 (0)