|
| 1 | +package workspaces |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "errors" |
| 6 | + "io" |
| 7 | + "strconv" |
| 8 | + "strings" |
| 9 | + |
| 10 | + "github.com/fastly/go-fastly/v12/fastly" |
| 11 | + "github.com/fastly/go-fastly/v12/fastly/ngwaf/v1/workspaces" |
| 12 | + |
| 13 | + "github.com/fastly/cli/pkg/argparser" |
| 14 | + fsterr "github.com/fastly/cli/pkg/errors" |
| 15 | + "github.com/fastly/cli/pkg/global" |
| 16 | + "github.com/fastly/cli/pkg/text" |
| 17 | +) |
| 18 | + |
| 19 | +// UpdateCommand calls the Fastly API to create domains. |
| 20 | +type UpdateCommand struct { |
| 21 | + argparser.Base |
| 22 | + argparser.JSONOutput |
| 23 | + |
| 24 | + // Required. |
| 25 | + workspaceID string |
| 26 | + |
| 27 | + // Optional. |
| 28 | + description argparser.OptionalString |
| 29 | + blockingMode argparser.OptionalString |
| 30 | + name argparser.OptionalString |
| 31 | + attackThresholds argparser.OptionalString |
| 32 | + defaultBlockingCode argparser.OptionalInt |
| 33 | + defaultRedirectURL argparser.OptionalString |
| 34 | + clientIPHeaders argparser.OptionalString |
| 35 | + ipAnonimization argparser.OptionalString |
| 36 | +} |
| 37 | + |
| 38 | +// NewUpdateCommand returns a usable command registered under the parent. |
| 39 | +func NewUpdateCommand(parent argparser.Registerer, g *global.Data) *UpdateCommand { |
| 40 | + c := UpdateCommand{ |
| 41 | + Base: argparser.Base{ |
| 42 | + Globals: g, |
| 43 | + }, |
| 44 | + } |
| 45 | + c.CmdClause = parent.Command("update", "Update a workspace") |
| 46 | + |
| 47 | + // Required. |
| 48 | + c.CmdClause.Flag("workspace-id", "Workspace ID").Required().StringVar(&c.workspaceID) |
| 49 | + |
| 50 | + // Optional. |
| 51 | + c.CmdClause.Flag("description", "User submitted description of a workspace.").Action(c.description.Set).StringVar(&c.description.Value) |
| 52 | + c.CmdClause.Flag("blockingMode", "User configured mode blocking mode.").Action(c.blockingMode.Set).StringVar(&c.blockingMode.Value) |
| 53 | + c.CmdClause.Flag("name", "User submitted display name of a workspace.").Action(c.name.Set).StringVar(&c.name.Value) |
| 54 | + c.CmdClause.Flag("attackThresholds", "Attack threshold parameters for system site alerts. Each threshold value is the number of attack signals per IP address that must be detected during the interval before the related IP address is flagged. Input accepted as colon separated string: Immediate:OneMinute:TenMinutes:OneHour").Action(c.attackThresholds.Set).StringVar(&c.attackThresholds.Value) |
| 55 | + c.CmdClause.Flag("clientIPHeaders", "Specify the request header containing the client IP address. Input accepted as colon separated string.").Action(c.clientIPHeaders.Set).StringVar(&c.clientIPHeaders.Value) |
| 56 | + c.CmdClause.Flag("defaultBlockingCode", "Default status code that is returned when a request to your web application is blocked.").Action(c.defaultBlockingCode.Set).IntVar(&c.defaultBlockingCode.Value) |
| 57 | + c.CmdClause.Flag("defaultRedirectURL", "Redirect url to be used if code 301 or 302 is used.").Action(c.defaultRedirectURL.Set).StringVar(&c.defaultRedirectURL.Value) |
| 58 | + c.CmdClause.Flag("ipAnonimization", "Agents will anonymize IP addresses according to the option selected.").Action(c.ipAnonimization.Set).StringVar(&c.ipAnonimization.Value) |
| 59 | + c.RegisterFlagBool(c.JSONFlag()) |
| 60 | + |
| 61 | + return &c |
| 62 | +} |
| 63 | + |
| 64 | +// Exec invokes the application logic for the command. |
| 65 | +func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) error { |
| 66 | + if c.Globals.Verbose() && c.JSONOutput.Enabled { |
| 67 | + return fsterr.ErrInvalidVerboseJSONCombo |
| 68 | + } |
| 69 | + var err error |
| 70 | + input := &workspaces.UpdateInput{ |
| 71 | + WorkspaceID: &c.workspaceID, |
| 72 | + } |
| 73 | + |
| 74 | + if c.blockingMode.WasSet { |
| 75 | + input.Mode = &c.blockingMode.Value |
| 76 | + } |
| 77 | + if c.description.WasSet { |
| 78 | + input.Description = &c.description.Value |
| 79 | + } |
| 80 | + if c.name.WasSet { |
| 81 | + input.Name = &c.name.Value |
| 82 | + } |
| 83 | + |
| 84 | + if c.attackThresholds.WasSet { |
| 85 | + input.AttackSignalThresholds, err = parseUpdateAttackSignalThresholds(c.attackThresholds.Value) |
| 86 | + if err != nil { |
| 87 | + return err |
| 88 | + } |
| 89 | + } |
| 90 | + if c.clientIPHeaders.WasSet { |
| 91 | + input.ClientIPHeaders = strings.Split(c.clientIPHeaders.Value, ":") |
| 92 | + } |
| 93 | + if c.defaultBlockingCode.WasSet { |
| 94 | + input.DefaultBlockingResponseCode = &c.defaultBlockingCode.Value |
| 95 | + } |
| 96 | + if c.defaultRedirectURL.WasSet { |
| 97 | + input.DefaultRedirectURL = &c.defaultRedirectURL.Value |
| 98 | + } |
| 99 | + if c.ipAnonimization.WasSet { |
| 100 | + input.IPAnonymization = &c.ipAnonimization.Value |
| 101 | + } |
| 102 | + |
| 103 | + fc, ok := c.Globals.APIClient.(*fastly.Client) |
| 104 | + if !ok { |
| 105 | + return errors.New("failed to convert interface to a fastly client") |
| 106 | + } |
| 107 | + |
| 108 | + data, err := workspaces.Update(context.TODO(), fc, input) |
| 109 | + if err != nil { |
| 110 | + return err |
| 111 | + } |
| 112 | + |
| 113 | + if ok, err := c.WriteJSON(out, data); ok { |
| 114 | + return err |
| 115 | + } |
| 116 | + |
| 117 | + text.Success(out, "Updated workspace '%s' (workspace-id: %s)", data.Name, data.WorkspaceID) |
| 118 | + return nil |
| 119 | +} |
| 120 | + |
| 121 | +func parseUpdateAttackSignalThresholds(thresholds string) (*workspaces.AttackSignalThresholdsUpdateInput, error) { |
| 122 | + thresholdsArray := strings.Split(thresholds, ":") |
| 123 | + if len(thresholdsArray) != 4 { |
| 124 | + return nil, errors.New("wrong number of inputs for Attack Signal Thresholds") |
| 125 | + } |
| 126 | + immediate, err := strconv.ParseBool(thresholdsArray[0]) |
| 127 | + if err != nil { |
| 128 | + return nil, err |
| 129 | + } |
| 130 | + oneMinute, err := strconv.Atoi(thresholdsArray[1]) |
| 131 | + if err != nil { |
| 132 | + return nil, err |
| 133 | + } |
| 134 | + tenMinutes, err := strconv.Atoi(thresholdsArray[2]) |
| 135 | + if err != nil { |
| 136 | + return nil, err |
| 137 | + } |
| 138 | + oneHour, err := strconv.Atoi(thresholdsArray[3]) |
| 139 | + if err != nil { |
| 140 | + return nil, err |
| 141 | + } |
| 142 | + |
| 143 | + return &workspaces.AttackSignalThresholdsUpdateInput{ |
| 144 | + OneMinute: &oneMinute, |
| 145 | + TenMinutes: &tenMinutes, |
| 146 | + OneHour: &oneHour, |
| 147 | + Immediate: &immediate, |
| 148 | + }, nil |
| 149 | +} |
0 commit comments