From f93dc8541785602790fc529d87ebe1f5bf839e83 Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 30 Jul 2019 20:31:11 +0800 Subject: [PATCH] nat create delete restful api finished --- cmd/climc/shell/natdtable.go | 74 +++++++++++ cmd/climc/shell/natdtables.go | 37 ------ cmd/climc/shell/natgateways.go | 9 ++ cmd/climc/shell/natstable.go | 73 +++++++++++ cmd/climc/shell/natstables.go | 37 ------ docs/index.yaml | 16 +-- docs/natgateway/dnatentries.yaml | 34 +++++ docs/natgateway/dnatentry.yaml | 22 ++++ docs/natgateway/dtable.yaml | 11 -- docs/natgateway/dtables.yaml | 18 --- docs/natgateway/natgateway.yaml | 6 +- docs/natgateway/natgateways.yaml | 6 +- docs/natgateway/snatentries.yaml | 36 +++++ docs/natgateway/snatentry.yaml | 22 ++++ docs/natgateway/stable.yaml | 11 -- docs/natgateway/stables.yaml | 20 --- docs/parameters/natgateway.yaml | 16 +-- docs/schemas/natgateway.yaml | 146 ++++++++++++++++----- go.sum | 2 - pkg/apis/compute/natgateway.go | 18 ++- pkg/compute/models/cloudsync.go | 8 +- pkg/compute/models/natdtable.go | 65 ++++++++- pkg/compute/models/natgateways.go | 27 +++- pkg/compute/models/natstable.go | 65 ++++++++- pkg/compute/models/purge.go | 4 +- pkg/compute/tasks/natdentry_create_task.go | 75 +++++++++++ pkg/compute/tasks/natdentry_delete_task.go | 65 +++++++++ pkg/compute/tasks/natsentry_create_task.go | 72 ++++++++++ pkg/compute/tasks/natsentry_delete_task.go | 65 +++++++++ pkg/mcclient/modules/mod_natdtables.go | 6 +- pkg/mcclient/modules/mod_natstables.go | 6 +- pkg/mcclient/options/natgateways.go | 31 +++++ 32 files changed, 878 insertions(+), 225 deletions(-) create mode 100644 cmd/climc/shell/natdtable.go delete mode 100644 cmd/climc/shell/natdtables.go create mode 100644 cmd/climc/shell/natstable.go delete mode 100644 cmd/climc/shell/natstables.go create mode 100644 docs/natgateway/dnatentries.yaml create mode 100644 docs/natgateway/dnatentry.yaml delete mode 100644 docs/natgateway/dtable.yaml delete mode 100644 docs/natgateway/dtables.yaml create mode 100644 docs/natgateway/snatentries.yaml create mode 100644 docs/natgateway/snatentry.yaml delete mode 100644 docs/natgateway/stable.yaml delete mode 100644 docs/natgateway/stables.yaml create mode 100644 pkg/compute/tasks/natdentry_create_task.go create mode 100644 pkg/compute/tasks/natdentry_delete_task.go create mode 100644 pkg/compute/tasks/natsentry_create_task.go create mode 100644 pkg/compute/tasks/natsentry_delete_task.go diff --git a/cmd/climc/shell/natdtable.go b/cmd/climc/shell/natdtable.go new file mode 100644 index 0000000000..7d805c8f40 --- /dev/null +++ b/cmd/climc/shell/natdtable.go @@ -0,0 +1,74 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shell + +import ( + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/mcclient/modules" + "yunion.io/x/onecloud/pkg/mcclient/options" +) + +func init() { + + R(&options.NatDTableListOptions{}, "dnat-list", "List DNAT entries", func(s *mcclient.ClientSession, opts *options.NatDTableListOptions) error { + params, err := options.ListStructToParams(opts) + if err != nil { + return err + } + result, err := modules.NatDTable.List(s, params) + if err != nil { + return err + } + printList(result, modules.NatDTable.GetColumns(s)) + return nil + }) + R(&options.NatDDeleteShowOptions{}, "dnat-delete", "Delete a DNAT", func(s *mcclient.ClientSession, args *options.NatDDeleteShowOptions) error { + results, err := modules.NatDTable.Delete(s, args.ID, nil) + if err != nil { + return err + } + printObject(results) + return nil + }) + R(&options.NatDDeleteShowOptions{}, "dnat-show", "Show a DNAT", func(s *mcclient.ClientSession, args *options.NatDDeleteShowOptions) error { + results, err := modules.NatDTable.Get(s, args.ID, nil) + if err != nil { + return err + } + printObject(results) + return nil + }) + + R(&options.NatDCreateOptions{}, "dnat-create", "Create a DNAT", func(s *mcclient.ClientSession, args *options.NatDCreateOptions) error { + params := jsonutils.NewDict() + params.Add(jsonutils.NewString(args.NAME), "name") + params.Add(jsonutils.NewString(args.NATGATEWAYID), "natgateway_id") + params.Add(jsonutils.NewString(args.INTERNALIP), "internal_ip") + params.Add(jsonutils.NewString(args.INTERNALPORT), "internal_port") + params.Add(jsonutils.NewString(args.EXTERNALIP), "external_ip") + params.Add(jsonutils.NewString(args.EXTERNALIPID), "external_ip_id") + params.Add(jsonutils.NewString(args.EXTERNALPORT), "external_port") + params.Add(jsonutils.NewString(args.IPPROTOCOL), "ip_protocol") + + result, err := modules.NatDTable.Create(s, params) + if err != nil { + return err + } + printObject(result) + return nil + }) +} diff --git a/cmd/climc/shell/natdtables.go b/cmd/climc/shell/natdtables.go deleted file mode 100644 index a1053746dd..0000000000 --- a/cmd/climc/shell/natdtables.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019 Yunion -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package shell - -import ( - "yunion.io/x/onecloud/pkg/mcclient" - "yunion.io/x/onecloud/pkg/mcclient/modules" - "yunion.io/x/onecloud/pkg/mcclient/options" -) - -func init() { - - R(&options.NatDTableListOptions{}, "natdtable-list", "List DNAT tables", func(s *mcclient.ClientSession, opts *options.NatDTableListOptions) error { - params, err := options.ListStructToParams(opts) - if err != nil { - return err - } - result, err := modules.NatDTables.List(s, params) - if err != nil { - return err - } - printList(result, modules.NatDTables.GetColumns(s)) - return nil - }) -} diff --git a/cmd/climc/shell/natgateways.go b/cmd/climc/shell/natgateways.go index 221cc35a5c..032ab83e9a 100644 --- a/cmd/climc/shell/natgateways.go +++ b/cmd/climc/shell/natgateways.go @@ -34,4 +34,13 @@ func init() { printList(result, modules.NatGateways.GetColumns(s)) return nil }) + + R(&options.NatGatewayShowOptions{}, "natgateway-show", "Show a NAT gateway", func(s *mcclient.ClientSession, args *options.NatGatewayShowOptions) error { + results, err := modules.NatGateways.Get(s, args.ID, nil) + if err != nil { + return err + } + printObject(results) + return nil + }) } diff --git a/cmd/climc/shell/natstable.go b/cmd/climc/shell/natstable.go new file mode 100644 index 0000000000..ad2288ef07 --- /dev/null +++ b/cmd/climc/shell/natstable.go @@ -0,0 +1,73 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shell + +import ( + "yunion.io/x/jsonutils" + + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/mcclient/modules" + "yunion.io/x/onecloud/pkg/mcclient/options" +) + +func init() { + + R(&options.NatSTableListOptions{}, "snat-list", "List SNAT entries", func(s *mcclient.ClientSession, opts *options.NatSTableListOptions) error { + params, err := options.ListStructToParams(opts) + if err != nil { + return err + } + result, err := modules.NatSTable.List(s, params) + if err != nil { + return err + } + printList(result, modules.NatSTable.GetColumns(s)) + return nil + }) + R(&options.NatSDeleteShowOptions{}, "snat-delete", "Delete a SNAT", func(s *mcclient.ClientSession, args *options.NatSDeleteShowOptions) error { + results, err := modules.NatSTable.Delete(s, args.ID, nil) + if err != nil { + return err + } + printObject(results) + return nil + }) + + R(&options.NatSDeleteShowOptions{}, "snat-show", "Show a SNAT", func(s *mcclient.ClientSession, args *options.NatSDeleteShowOptions) error { + results, err := modules.NatSTable.Get(s, args.ID, nil) + if err != nil { + return err + } + printObject(results) + return nil + }) + + R(&options.NatSCreateOptions{}, "snat-create", "Create a SNAT", func(s *mcclient.ClientSession, args *options.NatSCreateOptions) error { + params := jsonutils.NewDict() + params.Add(jsonutils.NewString(args.NAME), "name") + params.Add(jsonutils.NewString(args.NATGATEWAYID), "natgateway_id") + params.Add(jsonutils.NewString(args.IP), "ip") + params.Add(jsonutils.NewString(args.EXTERNALIPID), "external_ip_id") + params.Add(jsonutils.NewString(args.SOURCECIDR), "source_cidr") + + result, err := modules.NatSTable.Create(s, params) + if err != nil { + return err + } + printObject(result) + return nil + }) + +} diff --git a/cmd/climc/shell/natstables.go b/cmd/climc/shell/natstables.go deleted file mode 100644 index 7a4e7058b7..0000000000 --- a/cmd/climc/shell/natstables.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019 Yunion -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package shell - -import ( - "yunion.io/x/onecloud/pkg/mcclient" - "yunion.io/x/onecloud/pkg/mcclient/modules" - "yunion.io/x/onecloud/pkg/mcclient/options" -) - -func init() { - - R(&options.NatSTableListOptions{}, "natstable-list", "List SNAT tables", func(s *mcclient.ClientSession, opts *options.NatSTableListOptions) error { - params, err := options.ListStructToParams(opts) - if err != nil { - return err - } - result, err := modules.NatSTables.List(s, params) - if err != nil { - return err - } - printList(result, modules.NatSTables.GetColumns(s)) - return nil - }) -} diff --git a/docs/index.yaml b/docs/index.yaml index fc5cab7aea..9c3e2a19b2 100644 --- a/docs/index.yaml +++ b/docs/index.yaml @@ -243,14 +243,14 @@ paths: $ref: "./natgateway/natgateways.yaml" /natgateways/{natgatewayId}: $ref: "./natgateway/natgateway.yaml" - /natdtables: - $ref: "./natgateway/dtables.yaml" - /natdtables/{dtableId}: - $ref: "./natgateway/dtable.yaml" - /natstables: - $ref: "./natgateway/stables.yaml" - /natstables/{stableId}: - $ref: "./natgateway/stable.yaml" + /natdentries: + $ref: "./natgateway/dnatentries.yaml" + /natdentries/{dnatentryId}: + $ref: "./natgateway/dnatentry.yaml" + /natsentries: + $ref: "./natgateway/snatentries.yaml" + /natsentries/{snatentryId}: + $ref: "./natgateway/snatentry.yaml" /loadbalancers: $ref: "./loadbalancer/loadbalancers.yaml" diff --git a/docs/natgateway/dnatentries.yaml b/docs/natgateway/dnatentries.yaml new file mode 100644 index 0000000000..21789787e9 --- /dev/null +++ b/docs/natgateway/dnatentries.yaml @@ -0,0 +1,34 @@ +get: + summary: 按指定条件列出Nat网关DNat + parameters: + - $ref: "../parameters/common.yaml#/offset" + - $ref: "../parameters/common.yaml#/limit" + - $ref: "../parameters/common.yaml#/provider" + - $ref: "../parameters/common.yaml#/account" + - $ref: "../parameters/common.yaml#/cloudprovider" + - $ref: "../parameters/common.yaml#/brand" + + - $ref: "../parameters/natgateway.yaml#/natgateway" + responses: + 200: + description: Nat网关 DNat + schema: + $ref: "../schemas/natgateway.yaml#/DNatEntryListResponse" + tags: + - natdentry + +post: + summary: 创建DNat + parameters: + - in: body + name: dnatentry + required: true + schema: + $ref: '../schemas/natgateway.yaml#/DNatEntryCreate' + responses: + 200: + description: 新建DNat的信息 + schema: + $ref: '../schemas/natgateway.yaml#/DNatEntryResponse' + tags: + - natdentry diff --git a/docs/natgateway/dnatentry.yaml b/docs/natgateway/dnatentry.yaml new file mode 100644 index 0000000000..4d2a619896 --- /dev/null +++ b/docs/natgateway/dnatentry.yaml @@ -0,0 +1,22 @@ +get: + summary: 获取指定DNat详情信息 + parameters: + - $ref: "../parameters/natgateway.yaml#/dnatentryId" + responses: + 200: + description: DNat信息 + schema: + $ref: "../schemas/natgateway.yaml#/DNatEntryResponse" + tags: + - natdentry + +delete: + summary: 删除指定DNat + parameters: + - $ref: '../parameters/natgateway.yaml#/dnatentryId' + responses: + 200: + schema: + $ref: '../schemas/natgateway.yaml#/DNatEntryResponse' + tags: + - natdentry diff --git a/docs/natgateway/dtable.yaml b/docs/natgateway/dtable.yaml deleted file mode 100644 index 8f9758b922..0000000000 --- a/docs/natgateway/dtable.yaml +++ /dev/null @@ -1,11 +0,0 @@ -get: - summary: 获取指定SNAT详情信息 - parameters: - - $ref: "../parameters/natgateway.yaml#/dtableId" - responses: - 200: - description: DNAT信息 - schema: - $ref: "../schemas/natgateway.yaml#/DTableResponse" - tags: - - DNAT diff --git a/docs/natgateway/dtables.yaml b/docs/natgateway/dtables.yaml deleted file mode 100644 index b1a1d67cc4..0000000000 --- a/docs/natgateway/dtables.yaml +++ /dev/null @@ -1,18 +0,0 @@ -get: - summary: 按指定条件列出NAT网关DNAT - parameters: - - $ref: "../parameters/common.yaml#/offset" - - $ref: "../parameters/common.yaml#/limit" - - $ref: "../parameters/common.yaml#/provider" - - $ref: "../parameters/common.yaml#/account" - - $ref: "../parameters/common.yaml#/cloudprovider" - - $ref: "../parameters/common.yaml#/brand" - - - $ref: "../parameters/natgateway.yaml#/natgateway" - responses: - 200: - description: NAT网关 DNAT - schema: - $ref: "../schemas/natgateway.yaml#/DTableListResponse" - tags: - - DNAT diff --git a/docs/natgateway/natgateway.yaml b/docs/natgateway/natgateway.yaml index b9f421ca2d..038e666fa6 100644 --- a/docs/natgateway/natgateway.yaml +++ b/docs/natgateway/natgateway.yaml @@ -1,11 +1,11 @@ get: - summary: 获取指定DNAT详情信息 + summary: 获取指定Nat详情信息 parameters: - $ref: "../parameters/natgateway.yaml#/natgatewayId" responses: 200: - description: NAT网关信息 + description: Nat网关信息 schema: $ref: "../schemas/natgateway.yaml#/NatGatewayResponse" tags: - - NAT + - natgateway diff --git a/docs/natgateway/natgateways.yaml b/docs/natgateway/natgateways.yaml index e3a9e14636..4c448149e5 100644 --- a/docs/natgateway/natgateways.yaml +++ b/docs/natgateway/natgateways.yaml @@ -1,5 +1,5 @@ get: - summary: 按指定条件列出NAT网关 + summary: 按指定条件列出Nat网关 parameters: - $ref: "../parameters/common.yaml#/offset" - $ref: "../parameters/common.yaml#/limit" @@ -11,8 +11,8 @@ get: - $ref: "../parameters/common.yaml#/brand" responses: 200: - description: NAT网关列表信息 + description: Nat网关列表信息 schema: $ref: "../schemas/natgateway.yaml#/NatGatewayListResponse" tags: - - NAT + - natgateway diff --git a/docs/natgateway/snatentries.yaml b/docs/natgateway/snatentries.yaml new file mode 100644 index 0000000000..c4a3d7e4b6 --- /dev/null +++ b/docs/natgateway/snatentries.yaml @@ -0,0 +1,36 @@ +get: + summary: 按指定条件列出Nat网关SNat + parameters: + - $ref: "../parameters/common.yaml#/limit" + - $ref: "../parameters/common.yaml#/offset" + - $ref: "../parameters/common.yaml#/network" + - $ref: "../parameters/common.yaml#/provider" + - $ref: "../parameters/common.yaml#/account" + - $ref: "../parameters/common.yaml#/cloudprovider" + - $ref: "../parameters/common.yaml#/brand" + + - $ref: "../parameters/natgateway.yaml#/natgateway" + + responses: + 200: + description: Nat网关 SNat + schema: + $ref: "../schemas/natgateway.yaml#/SNatEntryListResponse" + tags: + - natsentry + +post: + summary: 创建SNat + parameters: + - in: body + name: snatentry + required: true + schema: + $ref: '../schemas/natgateway.yaml#/SNatEntryCreate' + responses: + 200: + description: 新建SNat的信息 + schema: + $ref: '../schemas/natgateway.yaml#/SNatEntryResponse' + tags: + - natsentry diff --git a/docs/natgateway/snatentry.yaml b/docs/natgateway/snatentry.yaml new file mode 100644 index 0000000000..a76dc1ba1d --- /dev/null +++ b/docs/natgateway/snatentry.yaml @@ -0,0 +1,22 @@ +get: + summary: 获取指定SNat详情信息 + parameters: + - $ref: "../parameters/natgateway.yaml#/snatentryId" + responses: + 200: + description: SNat信息 + schema: + $ref: "../schemas/natgateway.yaml#/SNatEntryResponse" + tags: + - natsentry + +delete: + summary: 删除指定SNat + parameters: + - $ref: '../parameters/natgateway.yaml#/snatentryId' + responses: + 200: + schema: + $ref: '../schemas/natgateway.yaml#/SNatEntryResponse' + tags: + - natsentry \ No newline at end of file diff --git a/docs/natgateway/stable.yaml b/docs/natgateway/stable.yaml deleted file mode 100644 index 06471c2c74..0000000000 --- a/docs/natgateway/stable.yaml +++ /dev/null @@ -1,11 +0,0 @@ -get: - summary: 获取指定SNAT详情信息 - parameters: - - $ref: "../parameters/natgateway.yaml#/stableId" - responses: - 200: - description: SNAT信息 - schema: - $ref: "../schemas/natgateway.yaml#/STableResponse" - tags: - - SNAT diff --git a/docs/natgateway/stables.yaml b/docs/natgateway/stables.yaml deleted file mode 100644 index 8b1e177790..0000000000 --- a/docs/natgateway/stables.yaml +++ /dev/null @@ -1,20 +0,0 @@ -get: - summary: 按指定条件列出NAT网关SNAT - parameters: - - $ref: "../parameters/common.yaml#/limit" - - $ref: "../parameters/common.yaml#/offset" - - $ref: "../parameters/common.yaml#/network" - - $ref: "../parameters/common.yaml#/provider" - - $ref: "../parameters/common.yaml#/account" - - $ref: "../parameters/common.yaml#/cloudprovider" - - $ref: "../parameters/common.yaml#/brand" - - - $ref: "../parameters/natgateway.yaml#/natgateway" - - responses: - 200: - description: NAT网关 SNAT - schema: - $ref: "../schemas/natgateway.yaml#/STableListResponse" - tags: - - SNAT diff --git a/docs/parameters/natgateway.yaml b/docs/parameters/natgateway.yaml index f1b98fbf81..74e5dbbdf5 100644 --- a/docs/parameters/natgateway.yaml +++ b/docs/parameters/natgateway.yaml @@ -3,20 +3,20 @@ natgatewayId: required: true in: path type: string - description: NAT网关名称或ID,建议使用ID -dtableId: - name: dtableId + description: NAT网关的ID +dnatentryId: + name: dnatentryId required: true in: path type: string - description: DNAT名称或ID,建议使用ID -stableId: - name: stableId + description: DNAT的ID +snatentryId: + name: snatentryId required: true in: path type: string - description: SNAT名称或ID,建议使用ID - + description: SNAT的ID + natgateway: name: natgateway in: query diff --git a/docs/schemas/natgateway.yaml b/docs/schemas/natgateway.yaml index dcd1272356..4ec091c7d0 100644 --- a/docs/schemas/natgateway.yaml +++ b/docs/schemas/natgateway.yaml @@ -36,7 +36,7 @@ NatGateway: type: string description: 区域ID example: 609c57b0-a5a7-4a5f-886c-950e1333cbd4 - external_id: + external_id: type: string description: 资源外部ID,对应纳管云上的ID example: ngw-2zexqebrmyohc1eqly153 @@ -64,13 +64,13 @@ NatGateway: type: string description: 区域ID example: f2c9efe0-b743-4de0-84ff-e40e37814ad3 - status: + status: type: string description: NAT网关状态 example: available updated_at: $ref: '#/UpdatedAt' - vpc: + vpc: type: string description: 网关VPC的名称 example: test-vpc @@ -91,13 +91,10 @@ NatGateway: description: 云平台类型 example: Qcloud - - - NatGatewayListResponse: type: object properties: - limit: + limit: type: integer example: 20 natgateways: @@ -108,7 +105,6 @@ NatGatewayListResponse: type: integer example: 124 - NatGatewayResponse: type: object properties: @@ -116,8 +112,7 @@ NatGatewayResponse: type: object $ref: '#/NatGateway' - -DTable: +DNatEntry: type: object properties: id: @@ -144,20 +139,20 @@ DTable: type: integer example: 8080 description: 内网端口 - external_ip: + external_ip: type: string example: 111.230.80.43 - description: 外网IP + description: 公网IP external_port: type: integer example: 432 - description: 外网端口 + description: 公网端口 ip_protocol: type: string description: 转发协议 enum: [udp,tcp,any] example: tcp - name: + name: type: string description: DNAT名称 example: 111.230.80.43/udp/32 @@ -173,32 +168,29 @@ DTable: type: string description: DNAT状态 example: available - - -DTableListResponse: + +DNatEntryListResponse: type: object properties: - limit: + limit: type: integer example: 20 - natdtables: + natdentries: type: array items: - $ref: '#/DTable' + $ref: '#/DNatEntry' total: type: integer example: 124 - -DTableResponse: +DNatEntryResponse: type: object properties: - natdtable: + natdentry: type: object - $ref: '#/DTable' + $ref: '#/DNatEntry' - -STable: +SNatEntry: type: object properties: id: @@ -249,24 +241,110 @@ STable: example: available description: SNAT状态 -STableListResponse: +SNatEntryListResponse: type: object properties: - limit: + limit: type: integer example: 20 - natstables: + natsentries: type: array items: - $ref: '#/STable' + $ref: '#/SNatEntry' total: type: integer example: 124 - -STableResponse: +SNatEntryResponse: type: object properties: - natstable: + natsentry: type: object - $ref: '#/STable' + $ref: '#/SNatEntry' + +DNatEntryCreate: + type: object + properties: + natdentry: + type: object + required: + - name + - natgateway_id + - internal_ip + - internal_port + - external_ip + - external_ip_id + - external_port + - ip_protocol + properties: + name: + type: string + example: ones + description: DNat的名字 + natgateway_id: + type: string + example: 378570ec-ded0-4b44-89ed-edce96eb32f7 + description: 所属NAT网关ID + internal_ip: + type: string + example: 10.0.42.4 + description: 内网IP + internal_port: + type: integer + example: 8080 + description: 内网端口 + external_ip: + type: string + example: 111.230.80.43 + description: 公网IP + external_ip_id: + type: string + example: "" + description: 公网IP对应的ID,除了华为云,可以为空 + external_port: + type: integer + example: 432 + description: 公网端口 + ip_protocol: + type: string + description: 转发协议 + enum: [udp,tcp,any] + example: tcp + +SNatEntryCreate: + type: object + properties: + natsentry: + type: object + required: + - name + - natgateway_id + - network_id + - ip + - external_ip_id + - source_cidr + properties: + name: + type: string + example: ones + description: SNat的名字 + natgateway_id: + type: string + example: 378570ec-ded0-4b44-89ed-edce96eb32f7 + description: 所属NAT网关ID + network_id: + type: string + example: 648a6baa-9827-49b1-8831-278a889154a1 + description: 所属网络ID + ip: + type: string + example: 49.4.12.184 + description: 公网IP + external_ip_id: + type: string + example: "" + description: 公网IP对应的ID,除了华为云,可以为空 + source_cidr: + type: string + example: 192.168.1.0/24 + description: 映射到公网IP的内网网段 diff --git a/go.sum b/go.sum index 5b1f5a1b82..633eccea10 100644 --- a/go.sum +++ b/go.sum @@ -494,8 +494,6 @@ yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d h1:59zrDL7Ft+hDukguJRmLr/Gdu/ yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U= yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf h1:OsKC+2ghZHwp+Ztm/MwKlLKKRiE7QcPG8eTp0GmsHbg= yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= -yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30 h1:6CkrwtX4xeYFqqpdWtQPAVqEnD3aEivPLOLzNKNPAB0= -yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224 h1:dAeUov/CtKcPaOapGVG7+NRqmUF2fr2O3Onb+ID5HS4= yunion.io/x/pkg v0.0.0-20190726033806-b564cfdcc224/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/sqlchemy v0.0.0-20190704155352-6aff6c803fda h1:i+/3Hh+kVmPZM1P+j3wfViEzb0XlttWyNvDSYA5DDDU= diff --git a/pkg/apis/compute/natgateway.go b/pkg/apis/compute/natgateway.go index 6c2cbfb7df..043190bcf6 100644 --- a/pkg/apis/compute/natgateway.go +++ b/pkg/apis/compute/natgateway.go @@ -15,12 +15,16 @@ package compute const ( - NAT_STAUTS_AVAILABLE = "available" //可用 - NAT_STATUS_ALLOCATE = "allocate" //创建中 - NAT_STATUS_DEPLOYING = "deploying" //配置中 - NAT_STATUS_UNKNOWN = "unknown" + NAT_STAUTS_AVAILABLE = "available" //可用 + NAT_STATUS_ALLOCATE = "allocate" //创建中 + NAT_STATUS_DEPLOYING = "deploying" //配置中 + NAT_STATUS_UNKNOWN = "unknown" + NAT_STATUS_FAILED = "failed" + NAT_STATUS_DELETED = "deleted" + NAT_STATUS_DELETING = "deleting" + NAT_STATUS_DELETE_FAILED = "delete_failed" - QCLOUD_NAT_SPEC_SMALL = "Small" - QCLOUD_NAT_SPEC_MIDDLE = "Middle" - QCLOUD_NAT_SPEC_LARGE = "Large" + QCLOUD_NAT_SPEC_SMALL = "small" + QCLOUD_NAT_SPEC_MIDDLE = "middle" + QCLOUD_NAT_SPEC_LARGE = "large" ) diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index 7992b6630a..f80e8211b3 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -316,9 +316,9 @@ func syncNatDTable(ctx context.Context, userCred mcclient.TokenCredential, provi log.Errorf(msg) return } - result := NatDEntryManager.SyncNatDTables(ctx, userCred, provider.GetOwnerId(), provider, localNatGateway, dtable) + result := NatDEntryManager.SyncNatDTable(ctx, userCred, provider.GetOwnerId(), provider, localNatGateway, dtable) msg := result.Result() - log.Infof("SyncNatDTables for NatGateway %s result: %s", localNatGateway.Name, msg) + log.Infof("SyncNatDTable for NatGateway %s result: %s", localNatGateway.Name, msg) if result.IsError() { return } @@ -332,9 +332,9 @@ func syncNatSTable(ctx context.Context, userCred mcclient.TokenCredential, provi log.Errorf(msg) return } - result := NatSEntryManager.SyncNatSTables(ctx, userCred, provider.GetOwnerId(), provider, localNatGateway, stable) + result := NatSEntryManager.SyncNatSTable(ctx, userCred, provider.GetOwnerId(), provider, localNatGateway, stable) msg := result.Result() - log.Infof("SyncNatSTables for NatGateway %s result: %s", localNatGateway.Name, msg) + log.Infof("SyncNatSTable for NatGateway %s result: %s", localNatGateway.Name, msg) if result.IsError() { return } diff --git a/pkg/compute/models/natdtable.go b/pkg/compute/models/natdtable.go index ee3fd0cec6..57ea7f96e1 100644 --- a/pkg/compute/models/natdtable.go +++ b/pkg/compute/models/natdtable.go @@ -19,15 +19,16 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/compare" "yunion.io/x/sqlchemy" api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" - "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" ) @@ -42,8 +43,8 @@ func init() { SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager( SNatDEntry{}, "natdtables_tbl", - "natdtable", - "natdtables", + "natdentry", + "natdentries", ), } NatDEntryManager.SetVirtualObject(NatDEntryManager) @@ -119,15 +120,18 @@ func (man *SNatDEntryManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ } func (man *SNatDEntryManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - return nil, httperrors.NewNotImplementedError("Not Implemented") + if !data.Contains("external_ip_id") { + return nil, errors.Error("Request body should contain key 'externalIpId'") + } + return data, nil } -func (manager *SNatDEntryManager) SyncNatDTables(ctx context.Context, userCred mcclient.TokenCredential, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider, nat *SNatGateway, extDTable []cloudprovider.ICloudNatDEntry) compare.SyncResult { +func (manager *SNatDEntryManager) SyncNatDTable(ctx context.Context, userCred mcclient.TokenCredential, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider, nat *SNatGateway, extDTable []cloudprovider.ICloudNatDEntry) compare.SyncResult { lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId)) defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId)) result := compare.SyncResult{} - dbNatDTables, err := nat.GetDTables() + dbNatDTables, err := nat.GetDTable() if err != nil { result.Error(err) return result @@ -249,3 +253,52 @@ func (self *SNatDEntry) GetCustomizeColumns(ctx context.Context, userCred mcclie extra.Add(jsonutils.NewString(natgateway.Name), "natgateway") return extra } + +func (self *SNatDEntry) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) { + if len(self.NatgatewayId) == 0 { + return + } + // ValidateCreateData function make data must contain 'externalIpId' key + externalIPID, _ := data.GetString("external_ip_id") + taskData := jsonutils.NewDict() + taskData.Set("external_ip_id", jsonutils.NewString(externalIPID)) + task, err := taskman.TaskManager.NewTask(ctx, "SNatDEntryCreateTask", self, userCred, taskData, "", "", nil) + if err != nil { + log.Errorf("SNatDEntryCreateTask newTask error %s", err) + } else { + task.ScheduleRun(nil) + } +} + +func (self *SNatDEntry) GetINatGateway() (cloudprovider.ICloudNatGateway, error) { + model, err := NatGatewayManager.FetchById(self.NatgatewayId) + if err != nil { + return nil, errors.Wrapf(err, "Fetch NatGateway whose id is %s failed", self.NatgatewayId) + } + natgateway := model.(*SNatGateway) + return natgateway.GetINatGateway() +} + +func (self *SNatDEntry) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + if len(self.ExternalId) > 0 { + return self.startDeleteVpcTask(ctx, userCred) + } else { + return self.realDelete(ctx, userCred) + } +} + +func (self *SNatDEntry) realDelete(ctx context.Context, userCred mcclient.TokenCredential) error { + db.OpsLog.LogEvent(self, db.ACT_DELOCATE, self.GetShortDesc(ctx), userCred) + self.SetStatus(userCred, api.NAT_STATUS_DELETED, "real delete") + return nil +} + +func (self *SNatDEntry) startDeleteVpcTask(ctx context.Context, userCred mcclient.TokenCredential) error { + task, err := taskman.TaskManager.NewTask(ctx, "SNatDEntryDeleteTask", self, userCred, nil, "", "", nil) + if err != nil { + log.Errorf("Start dnatEntry deleteTask fail %s", err) + return err + } + task.ScheduleRun(nil) + return nil +} diff --git a/pkg/compute/models/natgateways.go b/pkg/compute/models/natgateways.go index 8062e7da50..84ed561c76 100644 --- a/pkg/compute/models/natgateways.go +++ b/pkg/compute/models/natgateways.go @@ -19,6 +19,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/compare" "yunion.io/x/sqlchemy" @@ -127,7 +128,7 @@ func (manager *SNatGetewayManager) getNatgatewaysByProviderId(providerId string) return nats, nil } -func (self *SNatGateway) GetDTables() ([]SNatDEntry, error) { +func (self *SNatGateway) GetDTable() ([]SNatDEntry, error) { tables := []SNatDEntry{} q := NatDEntryManager.Query().Equals("natgateway_id", self.Id) err := db.FetchModelObjects(NatDEntryManager, q, &tables) @@ -137,7 +138,7 @@ func (self *SNatGateway) GetDTables() ([]SNatDEntry, error) { return tables, nil } -func (self *SNatGateway) GetSTables() ([]SNatSEntry, error) { +func (self *SNatGateway) GetSTable() ([]SNatSEntry, error) { tables := []SNatSEntry{} q := NatSEntryManager.Query().Equals("natgateway_id", self.Id) err := db.FetchModelObjects(NatSEntryManager, q, &tables) @@ -364,3 +365,25 @@ func (self *SNatGateway) SyncNatGatewayEips(ctx context.Context, userCred mcclie return result } + +func (self *SNatGateway) GetINatGateway() (cloudprovider.ICloudNatGateway, error) { + model, err := VpcManager.FetchById(self.VpcId) + if err != nil { + return nil, errors.Wrap(err, "Fetch vpc by ID failed") + } + vpc := model.(*SVpc) + cloudVpc, err := vpc.GetIVpc() + if err != nil { + return nil, errors.Wrap(err, "Fetch IVpc failed") + } + cloudNatGateways, err := cloudVpc.GetINatGateways() + if err != nil { + return nil, errors.Wrapf(err, "Get INatGateways of vpc %s failed", cloudVpc.GetGlobalId()) + } + for i := range cloudNatGateways { + if cloudNatGateways[i].GetGlobalId() == self.ExternalId { + return cloudNatGateways[i], nil + } + } + return nil, errors.Error("CloudNatGateway Not Found") +} diff --git a/pkg/compute/models/natstable.go b/pkg/compute/models/natstable.go index 282827c57a..fcd682747b 100644 --- a/pkg/compute/models/natstable.go +++ b/pkg/compute/models/natstable.go @@ -19,15 +19,16 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/compare" "yunion.io/x/sqlchemy" api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" - "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" ) @@ -42,8 +43,8 @@ func init() { SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager( SNatSEntry{}, "natstables_tbl", - "natstable", - "natstables", + "natsentry", + "natsentries", ), } NatSEntryManager.SetVirtualObject(NatSEntryManager) @@ -125,15 +126,18 @@ func (man *SNatSEntryManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ } func (man *SNatSEntryManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - return nil, httperrors.NewNotImplementedError("Not Implemented") + if !data.Contains("external_ip_id") { + return nil, errors.Error("Request body should contain key 'externalIpId'") + } + return data, nil } -func (manager *SNatSEntryManager) SyncNatSTables(ctx context.Context, userCred mcclient.TokenCredential, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider, nat *SNatGateway, extTable []cloudprovider.ICloudNatSEntry) compare.SyncResult { +func (manager *SNatSEntryManager) SyncNatSTable(ctx context.Context, userCred mcclient.TokenCredential, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider, nat *SNatGateway, extTable []cloudprovider.ICloudNatSEntry) compare.SyncResult { lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId)) defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId)) result := compare.SyncResult{} - dbNatSTables, err := nat.GetSTables() + dbNatSTables, err := nat.GetSTable() if err != nil { result.Error(err) return result @@ -270,3 +274,52 @@ func (self *SNatSEntry) GetCustomizeColumns(ctx context.Context, userCred mcclie extra.Add(jsonutils.NewString(network.Name), "network") return extra } + +func (self *SNatSEntry) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) { + if len(self.NatgatewayId) == 0 { + return + } + // ValidateCreateData function make data must contain 'externalIpId' key + externalIPID, _ := data.GetString("external_ip_id") + taskData := jsonutils.NewDict() + taskData.Set("external_ip_id", jsonutils.NewString(externalIPID)) + task, err := taskman.TaskManager.NewTask(ctx, "SNatSEntryCreateTask", self, userCred, taskData, "", "", nil) + if err != nil { + log.Errorf("SNatSEntryCreateTask newTask error %s", err) + } else { + task.ScheduleRun(nil) + } +} + +func (self *SNatSEntry) GetINatGateway() (cloudprovider.ICloudNatGateway, error) { + model, err := NatGatewayManager.FetchById(self.NatgatewayId) + if err != nil { + return nil, errors.Wrapf(err, "Fetch NatGateway whose id is %s failed", self.NatgatewayId) + } + natgateway := model.(*SNatGateway) + return natgateway.GetINatGateway() +} + +func (self *SNatSEntry) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + if len(self.ExternalId) > 0 { + return self.startDeleteVpcTask(ctx, userCred) + } else { + return self.realDelete(ctx, userCred) + } +} + +func (self *SNatSEntry) realDelete(ctx context.Context, userCred mcclient.TokenCredential) error { + db.OpsLog.LogEvent(self, db.ACT_DELOCATE, self.GetShortDesc(ctx), userCred) + self.SetStatus(userCred, api.NAT_STATUS_DELETED, "real delete") + return nil +} + +func (self *SNatSEntry) startDeleteVpcTask(ctx context.Context, userCred mcclient.TokenCredential) error { + task, err := taskman.TaskManager.NewTask(ctx, "SNatSEntryDeleteTask", self, userCred, nil, "", "", nil) + if err != nil { + log.Errorf("Start snatEntry deleteTask fail %s", err) + return err + } + task.ScheduleRun(nil) + return nil +} diff --git a/pkg/compute/models/purge.go b/pkg/compute/models/purge.go index 0ec12e7d61..e159ec4791 100644 --- a/pkg/compute/models/purge.go +++ b/pkg/compute/models/purge.go @@ -949,7 +949,7 @@ func (table *SNatSEntry) purge(ctx context.Context, userCred mcclient.TokenCrede } func (nat *SNatGateway) purgeSTables(ctx context.Context, userCred mcclient.TokenCredential) error { - tables, err := nat.GetSTables() + tables, err := nat.GetSTable() if err != nil { return err } @@ -976,7 +976,7 @@ func (table *SNatDEntry) purge(ctx context.Context, userCred mcclient.TokenCrede } func (nat *SNatGateway) purgeDTables(ctx context.Context, userCred mcclient.TokenCredential) error { - tables, err := nat.GetDTables() + tables, err := nat.GetDTable() if err != nil { return err } diff --git a/pkg/compute/tasks/natdentry_create_task.go b/pkg/compute/tasks/natdentry_create_task.go new file mode 100644 index 0000000000..fd15906496 --- /dev/null +++ b/pkg/compute/tasks/natdentry_create_task.go @@ -0,0 +1,75 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tasks + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" +) + +type SNatDEntryCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(SNatDEntryCreateTask{}) +} + +func (self *SNatDEntryCreateTask) TaskFailed(ctx context.Context, dnatEntry *models.SNatDEntry, err error) { + dnatEntry.SetStatus(self.UserCred, api.NAT_STATUS_FAILED, err.Error()) + db.OpsLog.LogEvent(dnatEntry, db.ACT_ALLOCATE_FAIL, err.Error(), self.UserCred) + logclient.AddActionLogWithStartable(self, dnatEntry, logclient.ACT_ALLOCATE, err.Error(), self.UserCred, false) + self.SetStageFailed(ctx, err.Error()) +} + +func (self *SNatDEntryCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { + dnatEntry := obj.(*models.SNatDEntry) + dnatEntry.SetStatus(self.UserCred, api.NAT_STATUS_ALLOCATE, "") + cloudNatGateway, err := dnatEntry.GetINatGateway() + if err != nil { + self.TaskFailed(ctx, dnatEntry, errors.Wrap(err, "Get NatGateway failed")) + return + } + + externalIPID, err := body.GetString("external_ip_id") + // construct a DNat RUle + dnatRule := cloudprovider.SNatDRule{ + Protocol: dnatEntry.IpProtocol, + InternalIP: dnatEntry.InternalIP, + InternalPort: dnatEntry.InternalPort, + ExternalIP: dnatEntry.ExternalIP, + ExternalIPID: externalIPID, + ExternalPort: dnatEntry.ExternalPort, + } + _, err = cloudNatGateway.CreateINatDEntry(dnatRule) + if err != nil { + self.TaskFailed(ctx, dnatEntry, errors.Wrapf(err, "Create DNat Entry '%s' failed", dnatEntry.ExternalId)) + return + } + + dnatEntry.SetStatus(self.UserCred, api.NAT_STAUTS_AVAILABLE, "") + + logclient.AddActionLogWithStartable(self, dnatEntry, logclient.ACT_ALLOCATE, nil, self.UserCred, true) + self.SetStageComplete(ctx, nil) +} diff --git a/pkg/compute/tasks/natdentry_delete_task.go b/pkg/compute/tasks/natdentry_delete_task.go new file mode 100644 index 0000000000..0f19b4b3fb --- /dev/null +++ b/pkg/compute/tasks/natdentry_delete_task.go @@ -0,0 +1,65 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tasks + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" +) + +type SNatDEntryDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(SNatDEntryDeleteTask{}) +} + +func (self *SNatDEntryDeleteTask) taskFailed(ctx context.Context, dnatEntry *models.SNatDEntry, err error) { + dnatEntry.SetStatus(self.UserCred, api.NAT_STATUS_DELETE_FAILED, err.Error()) + db.OpsLog.LogEvent(dnatEntry, db.ACT_DELOCATE_FAIL, err.Error(), self.UserCred) + logclient.AddActionLogWithStartable(self, dnatEntry, logclient.ACT_DELETE, err.Error(), self.UserCred, false) + self.SetStageFailed(ctx, err.Error()) +} + +func (self *SNatDEntryDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { + dnatEntry := obj.(*models.SNatDEntry) + dnatEntry.SetStatus(self.UserCred, api.NAT_STATUS_ALLOCATE, "") + cloudNatGateway, err := dnatEntry.GetINatGateway() + if err != nil { + self.taskFailed(ctx, dnatEntry, errors.Wrap(err, "Get NatGateway failed")) + return + } + cloudNatDEntry, err := cloudNatGateway.GetINatDEntryByID(dnatEntry.ExternalId) + if err != nil { + self.taskFailed(ctx, dnatEntry, errors.Wrapf(err, "Get DNat Entry by ID '%s' failed", dnatEntry.ExternalId)) + } + err = cloudNatDEntry.Delete() + if err != nil { + self.taskFailed(ctx, dnatEntry, errors.Wrapf(err, "Delete DNat Entry '%s' failed", dnatEntry.ExternalId)) + } + dnatEntry.SetStatus(self.UserCred, api.NAT_STATUS_DELETED, "") + + logclient.AddActionLogWithStartable(self, dnatEntry, logclient.ACT_DELETE, nil, self.UserCred, true) + self.SetStageComplete(ctx, nil) +} diff --git a/pkg/compute/tasks/natsentry_create_task.go b/pkg/compute/tasks/natsentry_create_task.go new file mode 100644 index 0000000000..8aedece45d --- /dev/null +++ b/pkg/compute/tasks/natsentry_create_task.go @@ -0,0 +1,72 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tasks + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" +) + +type SNatSEntryCreateTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(SNatSEntryCreateTask{}) +} + +func (self *SNatSEntryCreateTask) TaskFailed(ctx context.Context, snatEntry *models.SNatSEntry, err error) { + snatEntry.SetStatus(self.UserCred, api.NAT_STATUS_FAILED, err.Error()) + db.OpsLog.LogEvent(snatEntry, db.ACT_ALLOCATE_FAIL, err.Error(), self.UserCred) + logclient.AddActionLogWithStartable(self, snatEntry, logclient.ACT_ALLOCATE, err.Error(), self.UserCred, false) + self.SetStageFailed(ctx, err.Error()) +} + +func (self *SNatSEntryCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { + snatEntry := obj.(*models.SNatSEntry) + snatEntry.SetStatus(self.UserCred, api.NAT_STATUS_ALLOCATE, "") + cloudNatGateway, err := snatEntry.GetINatGateway() + if err != nil { + self.TaskFailed(ctx, snatEntry, errors.Wrap(err, "Get NatGateway failed")) + return + } + + externalIPID, err := body.GetString("external_ip_id") + // construct a DNat RUle + snatRule := cloudprovider.SNatSRule{ + SourceCIDR: snatEntry.SourceCIDR, + ExternalIP: snatEntry.IP, + ExternalIPID: externalIPID, + } + _, err = cloudNatGateway.CreateINatSEntry(snatRule) + if err != nil { + self.TaskFailed(ctx, snatEntry, errors.Wrapf(err, "Create SNat Entry '%s' failed", snatEntry.ExternalId)) + return + } + + snatEntry.SetStatus(self.UserCred, api.NAT_STAUTS_AVAILABLE, "") + + logclient.AddActionLogWithStartable(self, snatEntry, logclient.ACT_ALLOCATE, nil, self.UserCred, true) + self.SetStageComplete(ctx, nil) +} diff --git a/pkg/compute/tasks/natsentry_delete_task.go b/pkg/compute/tasks/natsentry_delete_task.go new file mode 100644 index 0000000000..573f7a6d08 --- /dev/null +++ b/pkg/compute/tasks/natsentry_delete_task.go @@ -0,0 +1,65 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tasks + +import ( + "context" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudcommon/db" + "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" + "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" +) + +type SNatSEntryDeleteTask struct { + taskman.STask +} + +func init() { + taskman.RegisterTask(SNatSEntryDeleteTask{}) +} + +func (self *SNatSEntryDeleteTask) taskFailed(ctx context.Context, snatEntry *models.SNatSEntry, err error) { + snatEntry.SetStatus(self.UserCred, api.NAT_STATUS_DELETE_FAILED, err.Error()) + db.OpsLog.LogEvent(snatEntry, db.ACT_DELOCATE_FAIL, err.Error(), self.UserCred) + logclient.AddActionLogWithStartable(self, snatEntry, logclient.ACT_DELETE, err.Error(), self.UserCred, false) + self.SetStageFailed(ctx, err.Error()) +} + +func (self *SNatSEntryDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { + snatEntry := obj.(*models.SNatSEntry) + snatEntry.SetStatus(self.UserCred, api.NAT_STATUS_ALLOCATE, "") + cloudNatGateway, err := snatEntry.GetINatGateway() + if err != nil { + self.taskFailed(ctx, snatEntry, errors.Wrap(err, "Get NatGateway failed")) + return + } + cloudNatDEntry, err := cloudNatGateway.GetINatSEntryByID(snatEntry.ExternalId) + if err != nil { + self.taskFailed(ctx, snatEntry, errors.Wrapf(err, "Get SNat Entry by ID '%s' failed", snatEntry.ExternalId)) + } + err = cloudNatDEntry.Delete() + if err != nil { + self.taskFailed(ctx, snatEntry, errors.Wrapf(err, "Delete SNat Entry '%s' failed", snatEntry.ExternalId)) + } + snatEntry.SetStatus(self.UserCred, api.NAT_STATUS_DELETED, "") + + logclient.AddActionLogWithStartable(self, snatEntry, logclient.ACT_DELETE, nil, self.UserCred, true) + self.SetStageComplete(ctx, nil) +} diff --git a/pkg/mcclient/modules/mod_natdtables.go b/pkg/mcclient/modules/mod_natdtables.go index 70a053db04..06a349d149 100644 --- a/pkg/mcclient/modules/mod_natdtables.go +++ b/pkg/mcclient/modules/mod_natdtables.go @@ -15,13 +15,13 @@ package modules var ( - NatDTables ResourceManager + NatDTable ResourceManager ) func init() { - NatDTables = NewComputeManager("natdtable", "natdtables", + NatDTable = NewComputeManager("natdentry", "natdentries", []string{"ID", "Name", "Status", "Natgateway_Id", "Natgateway", "External_IP", "External_Port", "Internal_IP", "Internal_Port", "Ip_Protocol"}, []string{}) - registerCompute(&NatDTables) + registerCompute(&NatDTable) } diff --git a/pkg/mcclient/modules/mod_natstables.go b/pkg/mcclient/modules/mod_natstables.go index df6049b72f..bcfba837fd 100644 --- a/pkg/mcclient/modules/mod_natstables.go +++ b/pkg/mcclient/modules/mod_natstables.go @@ -15,13 +15,13 @@ package modules var ( - NatSTables ResourceManager + NatSTable ResourceManager ) func init() { - NatSTables = NewComputeManager("natstable", "natstables", + NatSTable = NewComputeManager("natsentry", "natsentries", []string{"ID", "Name", "Status", "IP", "Natgateway_Id", "Natgateway", "Network", "Network_Id", "Source_CIDR"}, []string{}) - registerCompute(&NatSTables) + registerCompute(&NatSTable) } diff --git a/pkg/mcclient/options/natgateways.go b/pkg/mcclient/options/natgateways.go index 5a9c19705c..3b2abd8291 100644 --- a/pkg/mcclient/options/natgateways.go +++ b/pkg/mcclient/options/natgateways.go @@ -33,3 +33,34 @@ type NatSTableListOptions struct { BaseListOptions } + +type NatDDeleteShowOptions struct { + ID string `help:"ID of the DNat"` +} + +type NatSDeleteShowOptions struct { + ID string `help:"ID of the SNat"` +} + +type NatGatewayShowOptions struct { + ID string `help:"ID of Nat Gateway"` +} + +type NatDCreateOptions struct { + NAME string `help:"DNAT's name"` + NATGATEWAYID string `help:"The nat gateway'id to which DNat belongs"` + INTERNALIP string `help:"Internal IP"` + INTERNALPORT string `help:"Internal Port"` + EXTERNALIP string `help:"External IP"` + EXTERNALIPID string `help:"External IP ID, can be empty except huawei Cloud"` + EXTERNALPORT string `help:"External Port"` + IPPROTOCOL string `help:"Transport Protocol(tcp|udp)"` +} + +type NatSCreateOptions struct { + NAME string `help:"SNAT's name"` + NATGATEWAYID string `help:"The nat gateway'id to which SNat belongs"` + IP string `help:"External IP"` + EXTERNALIPID string `help:"External IP ID, can be empty except huawei Cloud"` + SOURCECIDR string `help:"Source CIDR"` +}