-
Notifications
You must be signed in to change notification settings - Fork 224
/
remote.go
122 lines (108 loc) · 3.53 KB
/
remote.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package appconfig
import (
"context"
"fmt"
"github.com/superfly/flyctl/api"
"github.com/superfly/flyctl/client"
"github.com/superfly/flyctl/flaps"
"github.com/superfly/flyctl/gql"
"github.com/superfly/flyctl/internal/machine"
"github.com/superfly/flyctl/iostreams"
)
func FromRemoteApp(ctx context.Context, appName string) (*Config, error) {
apiClient := client.FromContext(ctx).API()
appCompact, err := apiClient.GetAppCompact(ctx, appName)
if err != nil {
return nil, fmt.Errorf("error getting app: %w", err)
}
return getConfig(ctx, apiClient, appCompact)
}
func FromAppCompact(ctx context.Context, appCompact *api.AppCompact) (*Config, error) {
apiClient := client.FromContext(ctx).API()
return getConfig(ctx, apiClient, appCompact)
}
func getConfig(ctx context.Context, apiClient *api.Client, appCompact *api.AppCompact) (*Config, error) {
appName := appCompact.Name
switch appCompact.PlatformVersion {
// Need a more elegant way to find out what side of detached we are on
case NomadPlatform, "detached":
serverCfg, err := apiClient.GetConfig(ctx, appName)
if err != nil {
return nil, err
}
cfg, err := FromDefinition(&serverCfg.Definition)
if err != nil {
return nil, err
}
if err := cfg.SetNomadPlatform(); err != nil {
return nil, err
}
cfg.AppName = appName
return cfg, nil
case MachinesPlatform:
cfg, err := getAppV2ConfigFromReleases(ctx, apiClient, appCompact.Name)
if cfg == nil {
cfg, err = getAppV2ConfigFromMachines(ctx, apiClient, appCompact)
}
if err != nil {
return nil, err
}
if err := cfg.SetMachinesPlatform(); err != nil {
return nil, err
}
cfg.AppName = appName
return cfg, nil
default:
if !appCompact.Deployed {
return nil, fmt.Errorf("Undeployed app '%s' has no platform version set", appName)
}
return nil, fmt.Errorf("likely a bug, unknown platform version '%s' for app '%s'. ", appCompact.PlatformVersion, appName)
}
}
func getAppV2ConfigFromMachines(ctx context.Context, apiClient *api.Client, appCompact *api.AppCompact) (*Config, error) {
var (
flapsClient = flaps.FromContext(ctx)
io = iostreams.FromContext(ctx)
)
activeMachines, err := machine.ListActive(ctx)
if err != nil {
return nil, fmt.Errorf("error listing active machines for %s app: %w", appCompact.Name, err)
}
machineSet := machine.NewMachineSet(flapsClient, io, activeMachines)
appConfig, warnings, err := FromAppAndMachineSet(ctx, appCompact, machineSet)
if err != nil {
return nil, fmt.Errorf("failed to grab app config from existing machines, error: %w", err)
}
if warnings != "" {
fmt.Fprintf(io.ErrOut, "WARNINGS:\n%s", warnings)
}
return appConfig, nil
}
func getAppV2ConfigFromReleases(ctx context.Context, apiClient *api.Client, appName string) (*Config, error) {
_ = `# @genqlient
query FlyctlConfigCurrentRelease($appName: String!) {
app(name:$appName) {
currentReleaseUnprocessed {
configDefinition
}
}
}
`
resp, err := gql.FlyctlConfigCurrentRelease(ctx, apiClient.GenqClient, appName)
if err != nil {
return nil, err
}
configDefinition := resp.App.CurrentReleaseUnprocessed.ConfigDefinition
if configDefinition == nil {
return nil, nil
}
configMapDefinition, ok := configDefinition.(map[string]any)
if !ok {
return nil, fmt.Errorf("likely a bug, could not convert config definition of type %T to api map[string]any", configDefinition)
}
appConfig, err := FromDefinition(api.DefinitionPtr(configMapDefinition))
if err != nil {
return nil, fmt.Errorf("error creating appv2 Config from api definition: %w", err)
}
return appConfig, err
}