diff --git a/api/manager/docs.go b/api/manager/docs.go
index 3a8c11197..6a70588e7 100644
--- a/api/manager/docs.go
+++ b/api/manager/docs.go
@@ -2342,6 +2342,279 @@ var doc = `{
}
}
},
+ "/security-groups/{id}/security-rules/{security_rule_id}": {
+ "put": {
+ "description": "Add SecurityRule to SecurityGroup",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityGroup"
+ ],
+ "summary": "Add SecurityRule to SecurityGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "security rule id",
+ "name": "security_rule_id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ },
+ "delete": {
+ "description": "Destroy SecurityRule to SecurityGroup",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityGroup"
+ ],
+ "summary": "Destroy SecurityRule to SecurityGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "security rule id",
+ "name": "security_rule_id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
+ "/security-rules": {
+ "get": {
+ "description": "Get SecurityRules",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Get SecurityRules",
+ "parameters": [
+ {
+ "type": "integer",
+ "default": 0,
+ "description": "current page",
+ "name": "page",
+ "in": "query",
+ "required": true
+ },
+ {
+ "maximum": 50,
+ "minimum": 2,
+ "type": "integer",
+ "default": 10,
+ "description": "return max item count, default 10, max 50",
+ "name": "per_page",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ },
+ "post": {
+ "description": "create by json config",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Create SecurityRule",
+ "parameters": [
+ {
+ "description": "SecurityRule",
+ "name": "SecurityRule",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/types.CreateSecurityRuleRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
+ "/security-rules/{id}": {
+ "get": {
+ "description": "Get SecurityRule by id",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Get SecurityRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ },
+ "patch": {
+ "description": "Update by json config",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Update SecurityRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "description": "SecurityRule",
+ "name": "SecurityRule",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/types.UpdateSecurityRuleRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
"/securityGroups/{id}": {
"delete": {
"description": "Destroy by id",
@@ -2380,6 +2653,44 @@ var doc = `{
}
}
},
+ "/securityRules/{id}": {
+ "delete": {
+ "description": "Destroy by id",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Destroy SecurityRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
"/user/signin/{name}": {
"get": {
"description": "oauth signin by json config",
@@ -3026,6 +3337,32 @@ var doc = `{
}
},
"model.SecurityGroup": {
+ "type": "object",
+ "properties": {
+ "bio": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "security_rules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "updated_at": {
+ "type": "string"
+ }
+ }
+ },
+ "model.SecurityRule": {
"type": "object",
"properties": {
"bio": {
@@ -3046,6 +3383,12 @@ var doc = `{
"proxy_domain": {
"type": "string"
},
+ "security_groups": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SecurityGroup"
+ }
+ },
"updated_at": {
"type": "string"
}
@@ -3142,9 +3485,6 @@ var doc = `{
},
"name": {
"type": "string"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3312,9 +3652,6 @@ var doc = `{
},
"scopes": {
"$ref": "#/definitions/types.SchedulerClusterScopes"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3356,6 +3693,20 @@ var doc = `{
}
},
"types.CreateSecurityGroupRequest": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "bio": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "types.CreateSecurityRuleRequest": {
"type": "object",
"required": [
"domain",
@@ -3511,9 +3862,6 @@ var doc = `{
},
"name": {
"type": "string"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3611,9 +3959,6 @@ var doc = `{
},
"scopes": {
"$ref": "#/definitions/types.SchedulerClusterScopes"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3648,6 +3993,17 @@ var doc = `{
}
},
"types.UpdateSecurityGroupRequest": {
+ "type": "object",
+ "properties": {
+ "bio": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "types.UpdateSecurityRuleRequest": {
"type": "object",
"properties": {
"bio": {
diff --git a/api/manager/swagger.json b/api/manager/swagger.json
index 9e55e8f5d..c885d652e 100644
--- a/api/manager/swagger.json
+++ b/api/manager/swagger.json
@@ -2328,6 +2328,279 @@
}
}
},
+ "/security-groups/{id}/security-rules/{security_rule_id}": {
+ "put": {
+ "description": "Add SecurityRule to SecurityGroup",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityGroup"
+ ],
+ "summary": "Add SecurityRule to SecurityGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "security rule id",
+ "name": "security_rule_id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ },
+ "delete": {
+ "description": "Destroy SecurityRule to SecurityGroup",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityGroup"
+ ],
+ "summary": "Destroy SecurityRule to SecurityGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "security rule id",
+ "name": "security_rule_id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
+ "/security-rules": {
+ "get": {
+ "description": "Get SecurityRules",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Get SecurityRules",
+ "parameters": [
+ {
+ "type": "integer",
+ "default": 0,
+ "description": "current page",
+ "name": "page",
+ "in": "query",
+ "required": true
+ },
+ {
+ "maximum": 50,
+ "minimum": 2,
+ "type": "integer",
+ "default": 10,
+ "description": "return max item count, default 10, max 50",
+ "name": "per_page",
+ "in": "query",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ },
+ "post": {
+ "description": "create by json config",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Create SecurityRule",
+ "parameters": [
+ {
+ "description": "SecurityRule",
+ "name": "SecurityRule",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/types.CreateSecurityRuleRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
+ "/security-rules/{id}": {
+ "get": {
+ "description": "Get SecurityRule by id",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Get SecurityRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ },
+ "patch": {
+ "description": "Update by json config",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Update SecurityRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ },
+ {
+ "description": "SecurityRule",
+ "name": "SecurityRule",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/types.UpdateSecurityRuleRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
"/securityGroups/{id}": {
"delete": {
"description": "Destroy by id",
@@ -2366,6 +2639,44 @@
}
}
},
+ "/securityRules/{id}": {
+ "delete": {
+ "description": "Destroy by id",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "SecurityRule"
+ ],
+ "summary": "Destroy SecurityRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "id",
+ "name": "id",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": ""
+ },
+ "400": {
+ "description": ""
+ },
+ "404": {
+ "description": ""
+ },
+ "500": {
+ "description": ""
+ }
+ }
+ }
+ },
"/user/signin/{name}": {
"get": {
"description": "oauth signin by json config",
@@ -3012,6 +3323,32 @@
}
},
"model.SecurityGroup": {
+ "type": "object",
+ "properties": {
+ "bio": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "security_rules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SecurityRule"
+ }
+ },
+ "updated_at": {
+ "type": "string"
+ }
+ }
+ },
+ "model.SecurityRule": {
"type": "object",
"properties": {
"bio": {
@@ -3032,6 +3369,12 @@
"proxy_domain": {
"type": "string"
},
+ "security_groups": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/model.SecurityGroup"
+ }
+ },
"updated_at": {
"type": "string"
}
@@ -3128,9 +3471,6 @@
},
"name": {
"type": "string"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3298,9 +3638,6 @@
},
"scopes": {
"$ref": "#/definitions/types.SchedulerClusterScopes"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3342,6 +3679,20 @@
}
},
"types.CreateSecurityGroupRequest": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "bio": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "types.CreateSecurityRuleRequest": {
"type": "object",
"required": [
"domain",
@@ -3497,9 +3848,6 @@
},
"name": {
"type": "string"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3597,9 +3945,6 @@
},
"scopes": {
"$ref": "#/definitions/types.SchedulerClusterScopes"
- },
- "security_group_domain": {
- "type": "string"
}
}
},
@@ -3634,6 +3979,17 @@
}
},
"types.UpdateSecurityGroupRequest": {
+ "type": "object",
+ "properties": {
+ "bio": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "types.UpdateSecurityRuleRequest": {
"type": "object",
"properties": {
"bio": {
diff --git a/api/manager/swagger.yaml b/api/manager/swagger.yaml
index f8402300e..1ea6ddacc 100644
--- a/api/manager/swagger.yaml
+++ b/api/manager/swagger.yaml
@@ -181,6 +181,23 @@ definitions:
type: string
type: object
model.SecurityGroup:
+ properties:
+ bio:
+ type: string
+ created_at:
+ type: string
+ id:
+ type: integer
+ name:
+ type: string
+ security_rules:
+ items:
+ $ref: '#/definitions/model.SecurityRule'
+ type: array
+ updated_at:
+ type: string
+ type: object
+ model.SecurityRule:
properties:
bio:
type: string
@@ -194,6 +211,10 @@ definitions:
type: string
proxy_domain:
type: string
+ security_groups:
+ items:
+ $ref: '#/definitions/model.SecurityGroup'
+ type: array
updated_at:
type: string
type: object
@@ -255,8 +276,6 @@ definitions:
$ref: '#/definitions/types.CDNClusterConfig'
name:
type: string
- security_group_domain:
- type: string
required:
- config
- name
@@ -370,8 +389,6 @@ definitions:
type: string
scopes:
$ref: '#/definitions/types.SchedulerClusterScopes'
- security_group_domain:
- type: string
required:
- client_config
- config
@@ -404,6 +421,15 @@ definitions:
- scheduler_cluster_id
type: object
types.CreateSecurityGroupRequest:
+ properties:
+ bio:
+ type: string
+ name:
+ type: string
+ required:
+ - name
+ type: object
+ types.CreateSecurityRuleRequest:
properties:
bio:
type: string
@@ -507,8 +533,6 @@ definitions:
$ref: '#/definitions/types.CDNClusterConfig'
name:
type: string
- security_group_domain:
- type: string
type: object
types.UpdateCDNRequest:
properties:
@@ -572,8 +596,6 @@ definitions:
type: string
scopes:
$ref: '#/definitions/types.SchedulerClusterScopes'
- security_group_domain:
- type: string
type: object
types.UpdateSchedulerRequest:
properties:
@@ -596,6 +618,13 @@ definitions:
type: string
type: object
types.UpdateSecurityGroupRequest:
+ properties:
+ bio:
+ type: string
+ name:
+ type: string
+ type: object
+ types.UpdateSecurityRuleRequest:
properties:
bio:
type: string
@@ -2161,6 +2190,189 @@ paths:
summary: Add Scheduler to SecurityGroup
tags:
- SecurityGroup
+ /security-groups/{id}/security-rules/{security_rule_id}:
+ delete:
+ consumes:
+ - application/json
+ description: Destroy SecurityRule to SecurityGroup
+ parameters:
+ - description: id
+ in: path
+ name: id
+ required: true
+ type: string
+ - description: security rule id
+ in: path
+ name: security_rule_id
+ required: true
+ type: string
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: ""
+ "400":
+ description: ""
+ "404":
+ description: ""
+ "500":
+ description: ""
+ summary: Destroy SecurityRule to SecurityGroup
+ tags:
+ - SecurityGroup
+ put:
+ consumes:
+ - application/json
+ description: Add SecurityRule to SecurityGroup
+ parameters:
+ - description: id
+ in: path
+ name: id
+ required: true
+ type: string
+ - description: security rule id
+ in: path
+ name: security_rule_id
+ required: true
+ type: string
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: ""
+ "400":
+ description: ""
+ "404":
+ description: ""
+ "500":
+ description: ""
+ summary: Add SecurityRule to SecurityGroup
+ tags:
+ - SecurityGroup
+ /security-rules:
+ get:
+ consumes:
+ - application/json
+ description: Get SecurityRules
+ parameters:
+ - default: 0
+ description: current page
+ in: query
+ name: page
+ required: true
+ type: integer
+ - default: 10
+ description: return max item count, default 10, max 50
+ in: query
+ maximum: 50
+ minimum: 2
+ name: per_page
+ required: true
+ type: integer
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: OK
+ schema:
+ items:
+ $ref: '#/definitions/model.SecurityRule'
+ type: array
+ "400":
+ description: ""
+ "404":
+ description: ""
+ "500":
+ description: ""
+ summary: Get SecurityRules
+ tags:
+ - SecurityRule
+ post:
+ consumes:
+ - application/json
+ description: create by json config
+ parameters:
+ - description: SecurityRule
+ in: body
+ name: SecurityRule
+ required: true
+ schema:
+ $ref: '#/definitions/types.CreateSecurityRuleRequest'
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: OK
+ schema:
+ $ref: '#/definitions/model.SecurityRule'
+ "400":
+ description: ""
+ "404":
+ description: ""
+ "500":
+ description: ""
+ summary: Create SecurityRule
+ tags:
+ - SecurityRule
+ /security-rules/{id}:
+ get:
+ consumes:
+ - application/json
+ description: Get SecurityRule by id
+ parameters:
+ - description: id
+ in: path
+ name: id
+ required: true
+ type: string
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: OK
+ schema:
+ $ref: '#/definitions/model.SecurityRule'
+ "400":
+ description: ""
+ "404":
+ description: ""
+ "500":
+ description: ""
+ summary: Get SecurityRule
+ tags:
+ - SecurityRule
+ patch:
+ consumes:
+ - application/json
+ description: Update by json config
+ parameters:
+ - description: id
+ in: path
+ name: id
+ required: true
+ type: string
+ - description: SecurityRule
+ in: body
+ name: SecurityRule
+ required: true
+ schema:
+ $ref: '#/definitions/types.UpdateSecurityRuleRequest'
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: OK
+ schema:
+ $ref: '#/definitions/model.SecurityRule'
+ "400":
+ description: ""
+ "404":
+ description: ""
+ "500":
+ description: ""
+ summary: Update SecurityRule
+ tags:
+ - SecurityRule
/securityGroups/{id}:
delete:
consumes:
@@ -2186,6 +2398,31 @@ paths:
summary: Destroy SecurityGroup
tags:
- SecurityGroup
+ /securityRules/{id}:
+ delete:
+ consumes:
+ - application/json
+ description: Destroy by id
+ parameters:
+ - description: id
+ in: path
+ name: id
+ required: true
+ type: string
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: ""
+ "400":
+ description: ""
+ "404":
+ description: ""
+ "500":
+ description: ""
+ summary: Destroy SecurityRule
+ tags:
+ - SecurityRule
/user/signin/{name}:
get:
consumes:
diff --git a/docs/en/api-reference/api-reference.md b/docs/en/api-reference/api-reference.md
index 05382599e..386a78f7f 100644
--- a/docs/en/api-reference/api-reference.md
+++ b/docs/en/api-reference/api-reference.md
@@ -2337,6 +2337,268 @@ Add Scheduler to SecurityGroup
* SecurityGroup
+
+### Add SecurityRule to SecurityGroup
+```
+PUT /api/v1/security-groups/{id}/security-rules/{security_rule_id}
+```
+
+
+#### Description
+Add SecurityRule to SecurityGroup
+
+
+#### Parameters
+
+|Type|Name|Description|Schema|
+|---|---|---|---|
+|**Path**|**id**
*required*|id|string|
+|**Path**|**security_rule_id**
*required*|security rule id|string|
+
+
+#### Responses
+
+|HTTP Code|Schema|
+|---|---|
+|**200**|No Content|
+|**400**|No Content|
+|**404**|No Content|
+|**500**|No Content|
+
+
+#### Consumes
+
+* `application/json`
+
+
+#### Produces
+
+* `application/json`
+
+
+#### Tags
+
+* SecurityGroup
+
+
+
+### Destroy SecurityRule to SecurityGroup
+```
+DELETE /api/v1/security-groups/{id}/security-rules/{security_rule_id}
+```
+
+
+#### Description
+Destroy SecurityRule to SecurityGroup
+
+
+#### Parameters
+
+|Type|Name|Description|Schema|
+|---|---|---|---|
+|**Path**|**id**
*required*|id|string|
+|**Path**|**security_rule_id**
*required*|security rule id|string|
+
+
+#### Responses
+
+|HTTP Code|Schema|
+|---|---|
+|**200**|No Content|
+|**400**|No Content|
+|**404**|No Content|
+|**500**|No Content|
+
+
+#### Consumes
+
+* `application/json`
+
+
+#### Produces
+
+* `application/json`
+
+
+#### Tags
+
+* SecurityGroup
+
+
+
+### Create SecurityRule
+```
+POST /api/v1/security-rules
+```
+
+
+#### Description
+create by json config
+
+
+#### Parameters
+
+|Type|Name|Description|Schema|
+|---|---|---|---|
+|**Body**|**SecurityRule**
*required*|SecurityRule|[types.CreateSecurityRuleRequest](#types-createsecurityrulerequest)|
+
+
+#### Responses
+
+|HTTP Code|Description|Schema|
+|---|---|---|
+|**200**|OK|[model.SecurityRule](#model-securityrule)|
+|**400**||No Content|
+|**404**||No Content|
+|**500**||No Content|
+
+
+#### Consumes
+
+* `application/json`
+
+
+#### Produces
+
+* `application/json`
+
+
+#### Tags
+
+* SecurityRule
+
+
+
+### Get SecurityRules
+```
+GET /api/v1/security-rules
+```
+
+
+#### Description
+Get SecurityRules
+
+
+#### Parameters
+
+|Type|Name|Description|Schema|Default|
+|---|---|---|---|---|
+|**Query**|**page**
*required*|current page|integer|`0`|
+|**Query**|**per_page**
*required*|return max item count, default 10, max 50|integer|`10`|
+
+
+#### Responses
+
+|HTTP Code|Description|Schema|
+|---|---|---|
+|**200**|OK|< [model.SecurityRule](#model-securityrule) > array|
+|**400**||No Content|
+|**404**||No Content|
+|**500**||No Content|
+
+
+#### Consumes
+
+* `application/json`
+
+
+#### Produces
+
+* `application/json`
+
+
+#### Tags
+
+* SecurityRule
+
+
+
+### Get SecurityRule
+```
+GET /api/v1/security-rules/{id}
+```
+
+
+#### Description
+Get SecurityRule by id
+
+
+#### Parameters
+
+|Type|Name|Description|Schema|
+|---|---|---|---|
+|**Path**|**id**
*required*|id|string|
+
+
+#### Responses
+
+|HTTP Code|Description|Schema|
+|---|---|---|
+|**200**|OK|[model.SecurityRule](#model-securityrule)|
+|**400**||No Content|
+|**404**||No Content|
+|**500**||No Content|
+
+
+#### Consumes
+
+* `application/json`
+
+
+#### Produces
+
+* `application/json`
+
+
+#### Tags
+
+* SecurityRule
+
+
+
+### Update SecurityRule
+```
+PATCH /api/v1/security-rules/{id}
+```
+
+
+#### Description
+Update by json config
+
+
+#### Parameters
+
+|Type|Name|Description|Schema|
+|---|---|---|---|
+|**Path**|**id**
*required*|id|string|
+|**Body**|**SecurityRule**
*required*|SecurityRule|[types.UpdateSecurityRuleRequest](#types-updatesecurityrulerequest)|
+
+
+#### Responses
+
+|HTTP Code|Description|Schema|
+|---|---|---|
+|**200**|OK|[model.SecurityRule](#model-securityrule)|
+|**400**||No Content|
+|**404**||No Content|
+|**500**||No Content|
+
+
+#### Consumes
+
+* `application/json`
+
+
+#### Produces
+
+* `application/json`
+
+
+#### Tags
+
+* SecurityRule
+
+
### Destroy SecurityGroup
```
@@ -2380,6 +2642,49 @@ Destroy by id
* SecurityGroup
+
+### Destroy SecurityRule
+```
+DELETE /api/v1/securityRules/{id}
+```
+
+
+#### Description
+Destroy by id
+
+
+#### Parameters
+
+|Type|Name|Description|Schema|
+|---|---|---|---|
+|**Path**|**id**
*required*|id|string|
+
+
+#### Responses
+
+|HTTP Code|Schema|
+|---|---|
+|**200**|No Content|
+|**400**|No Content|
+|**404**|No Content|
+|**500**|No Content|
+
+
+#### Consumes
+
+* `application/json`
+
+
+#### Produces
+
+* `application/json`
+
+
+#### Tags
+
+* SecurityRule
+
+
### Oauth Signin
```
@@ -2885,6 +3190,19 @@ Get User by id
### model.SecurityGroup
+|Name|Schema|
+|---|---|
+|**bio**
*optional*|string|
+|**created_at**
*optional*|string|
+|**id**
*optional*|integer|
+|**name**
*optional*|string|
+|**security_rules**
*optional*|< [model.SecurityRule](#model-securityrule) > array|
+|**updated_at**
*optional*|string|
+
+
+
+### model.SecurityRule
+
|Name|Schema|
|---|---|
|**bio**
*optional*|string|
@@ -2893,6 +3211,7 @@ Get User by id
|**id**
*optional*|integer|
|**name**
*optional*|string|
|**proxy_domain**
*optional*|string|
+|**security_groups**
*optional*|< [model.SecurityGroup](#model-securitygroup) > array|
|**updated_at**
*optional*|string|
@@ -2948,7 +3267,6 @@ Get User by id
|**bio**
*optional*|string|
|**config**
*required*|[types.CDNClusterConfig](#types-cdnclusterconfig)|
|**name**
*required*|string|
-|**security_group_domain**
*optional*|string|
@@ -3023,7 +3341,6 @@ Get User by id
|**is_default**
*optional*|boolean|
|**name**
*required*|string|
|**scopes**
*optional*|[types.SchedulerClusterScopes](#types-schedulerclusterscopes)|
-|**security_group_domain**
*optional*|string|
@@ -3044,6 +3361,15 @@ Get User by id
### types.CreateSecurityGroupRequest
+|Name|Schema|
+|---|---|
+|**bio**
*optional*|string|
+|**name**
*required*|string|
+
+
+
+### types.CreateSecurityRuleRequest
+
|Name|Schema|
|---|---|
|**bio**
*optional*|string|
@@ -3140,7 +3466,6 @@ Get User by id
|**bio**
*optional*|string|
|**config**
*optional*|[types.CDNClusterConfig](#types-cdnclusterconfig)|
|**name**
*optional*|string|
-|**security_group_domain**
*optional*|string|
@@ -3200,7 +3525,6 @@ Get User by id
|**is_default**
*optional*|boolean|
|**name**
*optional*|string|
|**scopes**
*optional*|[types.SchedulerClusterScopes](#types-schedulerclusterscopes)|
-|**security_group_domain**
*optional*|string|
@@ -3221,6 +3545,15 @@ Get User by id
### types.UpdateSecurityGroupRequest
+|Name|Schema|
+|---|---|
+|**bio**
*optional*|string|
+|**name**
*optional*|string|
+
+
+
+### types.UpdateSecurityRuleRequest
+
|Name|Schema|
|---|---|
|**bio**
*optional*|string|
diff --git a/docs/zh-CN/api-reference/api-reference.md b/docs/zh-CN/api-reference/api-reference.md
index 9e53def36..4b8b3aeae 100644
--- a/docs/zh-CN/api-reference/api-reference.md
+++ b/docs/zh-CN/api-reference/api-reference.md
@@ -2337,6 +2337,268 @@ Add Scheduler to SecurityGroup
* SecurityGroup
+
+### Add SecurityRule to SecurityGroup
+```
+PUT /api/v1/security-groups/{id}/security-rules/{security_rule_id}
+```
+
+
+#### 说明
+Add SecurityRule to SecurityGroup
+
+
+#### 参数
+
+|类型|名称|说明|类型|
+|---|---|---|---|
+|**Path**|**id**
*必填*|id|string|
+|**Path**|**security_rule_id**
*必填*|security rule id|string|
+
+
+#### 响应
+
+|HTTP代码|类型|
+|---|---|
+|**200**|无内容|
+|**400**|无内容|
+|**404**|无内容|
+|**500**|无内容|
+
+
+#### 消耗
+
+* `application/json`
+
+
+#### 生成
+
+* `application/json`
+
+
+#### 标签
+
+* SecurityGroup
+
+
+
+### Destroy SecurityRule to SecurityGroup
+```
+DELETE /api/v1/security-groups/{id}/security-rules/{security_rule_id}
+```
+
+
+#### 说明
+Destroy SecurityRule to SecurityGroup
+
+
+#### 参数
+
+|类型|名称|说明|类型|
+|---|---|---|---|
+|**Path**|**id**
*必填*|id|string|
+|**Path**|**security_rule_id**
*必填*|security rule id|string|
+
+
+#### 响应
+
+|HTTP代码|类型|
+|---|---|
+|**200**|无内容|
+|**400**|无内容|
+|**404**|无内容|
+|**500**|无内容|
+
+
+#### 消耗
+
+* `application/json`
+
+
+#### 生成
+
+* `application/json`
+
+
+#### 标签
+
+* SecurityGroup
+
+
+
+### Create SecurityRule
+```
+POST /api/v1/security-rules
+```
+
+
+#### 说明
+create by json config
+
+
+#### 参数
+
+|类型|名称|说明|类型|
+|---|---|---|---|
+|**Body**|**SecurityRule**
*必填*|SecurityRule|[types.CreateSecurityRuleRequest](#types-createsecurityrulerequest)|
+
+
+#### 响应
+
+|HTTP代码|说明|类型|
+|---|---|---|
+|**200**|OK|[model.SecurityRule](#model-securityrule)|
+|**400**||无内容|
+|**404**||无内容|
+|**500**||无内容|
+
+
+#### 消耗
+
+* `application/json`
+
+
+#### 生成
+
+* `application/json`
+
+
+#### 标签
+
+* SecurityRule
+
+
+
+### Get SecurityRules
+```
+GET /api/v1/security-rules
+```
+
+
+#### 说明
+Get SecurityRules
+
+
+#### 参数
+
+|类型|名称|说明|类型|默认值|
+|---|---|---|---|---|
+|**Query**|**page**
*必填*|current page|integer|`0`|
+|**Query**|**per_page**
*必填*|return max item count, default 10, max 50|integer|`10`|
+
+
+#### 响应
+
+|HTTP代码|说明|类型|
+|---|---|---|
+|**200**|OK|< [model.SecurityRule](#model-securityrule) > array|
+|**400**||无内容|
+|**404**||无内容|
+|**500**||无内容|
+
+
+#### 消耗
+
+* `application/json`
+
+
+#### 生成
+
+* `application/json`
+
+
+#### 标签
+
+* SecurityRule
+
+
+
+### Get SecurityRule
+```
+GET /api/v1/security-rules/{id}
+```
+
+
+#### 说明
+Get SecurityRule by id
+
+
+#### 参数
+
+|类型|名称|说明|类型|
+|---|---|---|---|
+|**Path**|**id**
*必填*|id|string|
+
+
+#### 响应
+
+|HTTP代码|说明|类型|
+|---|---|---|
+|**200**|OK|[model.SecurityRule](#model-securityrule)|
+|**400**||无内容|
+|**404**||无内容|
+|**500**||无内容|
+
+
+#### 消耗
+
+* `application/json`
+
+
+#### 生成
+
+* `application/json`
+
+
+#### 标签
+
+* SecurityRule
+
+
+
+### Update SecurityRule
+```
+PATCH /api/v1/security-rules/{id}
+```
+
+
+#### 说明
+Update by json config
+
+
+#### 参数
+
+|类型|名称|说明|类型|
+|---|---|---|---|
+|**Path**|**id**
*必填*|id|string|
+|**Body**|**SecurityRule**
*必填*|SecurityRule|[types.UpdateSecurityRuleRequest](#types-updatesecurityrulerequest)|
+
+
+#### 响应
+
+|HTTP代码|说明|类型|
+|---|---|---|
+|**200**|OK|[model.SecurityRule](#model-securityrule)|
+|**400**||无内容|
+|**404**||无内容|
+|**500**||无内容|
+
+
+#### 消耗
+
+* `application/json`
+
+
+#### 生成
+
+* `application/json`
+
+
+#### 标签
+
+* SecurityRule
+
+
### Destroy SecurityGroup
```
@@ -2380,6 +2642,49 @@ Destroy by id
* SecurityGroup
+
+### Destroy SecurityRule
+```
+DELETE /api/v1/securityRules/{id}
+```
+
+
+#### 说明
+Destroy by id
+
+
+#### 参数
+
+|类型|名称|说明|类型|
+|---|---|---|---|
+|**Path**|**id**
*必填*|id|string|
+
+
+#### 响应
+
+|HTTP代码|类型|
+|---|---|
+|**200**|无内容|
+|**400**|无内容|
+|**404**|无内容|
+|**500**|无内容|
+
+
+#### 消耗
+
+* `application/json`
+
+
+#### 生成
+
+* `application/json`
+
+
+#### 标签
+
+* SecurityRule
+
+
### Oauth Signin
```
@@ -2885,6 +3190,19 @@ Get User by id
### model.SecurityGroup
+|名称|类型|
+|---|---|
+|**bio**
*可选*|string|
+|**created_at**
*可选*|string|
+|**id**
*可选*|integer|
+|**name**
*可选*|string|
+|**security_rules**
*可选*|< [model.SecurityRule](#model-securityrule) > array|
+|**updated_at**
*可选*|string|
+
+
+
+### model.SecurityRule
+
|名称|类型|
|---|---|
|**bio**
*可选*|string|
@@ -2893,6 +3211,7 @@ Get User by id
|**id**
*可选*|integer|
|**name**
*可选*|string|
|**proxy_domain**
*可选*|string|
+|**security_groups**
*可选*|< [model.SecurityGroup](#model-securitygroup) > array|
|**updated_at**
*可选*|string|
@@ -2948,7 +3267,6 @@ Get User by id
|**bio**
*可选*|string|
|**config**
*必填*|[types.CDNClusterConfig](#types-cdnclusterconfig)|
|**name**
*必填*|string|
-|**security_group_domain**
*可选*|string|
@@ -3023,7 +3341,6 @@ Get User by id
|**is_default**
*可选*|boolean|
|**name**
*必填*|string|
|**scopes**
*可选*|[types.SchedulerClusterScopes](#types-schedulerclusterscopes)|
-|**security_group_domain**
*可选*|string|
@@ -3044,6 +3361,15 @@ Get User by id
### types.CreateSecurityGroupRequest
+|名称|类型|
+|---|---|
+|**bio**
*可选*|string|
+|**name**
*必填*|string|
+
+
+
+### types.CreateSecurityRuleRequest
+
|名称|类型|
|---|---|
|**bio**
*可选*|string|
@@ -3140,7 +3466,6 @@ Get User by id
|**bio**
*可选*|string|
|**config**
*可选*|[types.CDNClusterConfig](#types-cdnclusterconfig)|
|**name**
*可选*|string|
-|**security_group_domain**
*可选*|string|
@@ -3200,7 +3525,6 @@ Get User by id
|**is_default**
*可选*|boolean|
|**name**
*可选*|string|
|**scopes**
*可选*|[types.SchedulerClusterScopes](#types-schedulerclusterscopes)|
-|**security_group_domain**
*可选*|string|
@@ -3221,6 +3545,15 @@ Get User by id
### types.UpdateSecurityGroupRequest
+|名称|类型|
+|---|---|
+|**bio**
*可选*|string|
+|**name**
*可选*|string|
+
+
+
+### types.UpdateSecurityRuleRequest
+
|名称|类型|
|---|---|
|**bio**
*可选*|string|
diff --git a/manager/database/database.go b/manager/database/database.go
index f409af27f..8c0072271 100644
--- a/manager/database/database.go
+++ b/manager/database/database.go
@@ -112,6 +112,7 @@ func migrate(db *gorm.DB) error {
&model.CDN{},
&model.SchedulerCluster{},
&model.Scheduler{},
+ &model.SecurityRule{},
&model.SecurityGroup{},
&model.User{},
&model.Oauth{},
diff --git a/manager/handlers/cdn_cluster.go b/manager/handlers/cdn_cluster.go
index 459003243..222a3ee30 100644
--- a/manager/handlers/cdn_cluster.go
+++ b/manager/handlers/cdn_cluster.go
@@ -44,17 +44,6 @@ func (h *Handlers) CreateCDNCluster(ctx *gin.Context) {
return
}
- if json.SecurityGroupDomain != "" {
- cdn, err := h.service.CreateCDNClusterWithSecurityGroupDomain(ctx.Request.Context(), json)
- if err != nil {
- ctx.Error(err) // nolint: errcheck
- return
- }
-
- ctx.JSON(http.StatusOK, cdn)
- return
- }
-
cdnCluster, err := h.service.CreateCDNCluster(ctx.Request.Context(), json)
if err != nil {
ctx.Error(err) // nolint: errcheck
@@ -115,17 +104,6 @@ func (h *Handlers) UpdateCDNCluster(ctx *gin.Context) {
return
}
- if json.SecurityGroupDomain != "" {
- cdn, err := h.service.UpdateCDNClusterWithSecurityGroupDomain(ctx.Request.Context(), params.ID, json)
- if err != nil {
- ctx.Error(err) // nolint: errcheck
- return
- }
-
- ctx.JSON(http.StatusOK, cdn)
- return
- }
-
cdnCluster, err := h.service.UpdateCDNCluster(ctx.Request.Context(), params.ID, json)
if err != nil {
ctx.Error(err) // nolint: errcheck
diff --git a/manager/handlers/scheduler_cluster.go b/manager/handlers/scheduler_cluster.go
index d55829ce7..c56c1efc1 100644
--- a/manager/handlers/scheduler_cluster.go
+++ b/manager/handlers/scheduler_cluster.go
@@ -44,17 +44,6 @@ func (h *Handlers) CreateSchedulerCluster(ctx *gin.Context) {
return
}
- if json.SecurityGroupDomain != "" {
- scheduler, err := h.service.CreateSchedulerClusterWithSecurityGroupDomain(ctx.Request.Context(), json)
- if err != nil {
- ctx.Error(err) // nolint: errcheck
- return
- }
-
- ctx.JSON(http.StatusOK, scheduler)
- return
- }
-
schedulerCluster, err := h.service.CreateSchedulerCluster(ctx.Request.Context(), json)
if err != nil {
ctx.Error(err) // nolint: errcheck
@@ -115,17 +104,6 @@ func (h *Handlers) UpdateSchedulerCluster(ctx *gin.Context) {
return
}
- if json.SecurityGroupDomain != "" {
- scheduler, err := h.service.UpdateSchedulerClusterWithSecurityGroupDomain(ctx.Request.Context(), params.ID, json)
- if err != nil {
- ctx.Error(err) // nolint: errcheck
- return
- }
-
- ctx.JSON(http.StatusOK, scheduler)
- return
- }
-
schedulerCluster, err := h.service.UpdateSchedulerCluster(ctx.Request.Context(), params.ID, json)
if err != nil {
ctx.Error(err) // nolint: errcheck
diff --git a/manager/handlers/security_group.go b/manager/handlers/security_group.go
index 99db28a86..4daa3ced3 100644
--- a/manager/handlers/security_group.go
+++ b/manager/handlers/security_group.go
@@ -225,3 +225,59 @@ func (h *Handlers) AddCDNClusterToSecurityGroup(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
+
+// @Summary Add SecurityRule to SecurityGroup
+// @Description Add SecurityRule to SecurityGroup
+// @Tags SecurityGroup
+// @Accept json
+// @Produce json
+// @Param id path string true "id"
+// @Param security_rule_id path string true "security rule id"
+// @Success 200
+// @Failure 400
+// @Failure 404
+// @Failure 500
+// @Router /security-groups/{id}/security-rules/{security_rule_id} [put]
+func (h *Handlers) AddSecurityRuleToSecurityGroup(ctx *gin.Context) {
+ var params types.AddSecurityRuleToSecurityGroupParams
+ if err := ctx.ShouldBindUri(¶ms); err != nil {
+ ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
+ return
+ }
+
+ err := h.service.AddSecurityRuleToSecurityGroup(ctx.Request.Context(), params.ID, params.SecurityRuleID)
+ if err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ ctx.Status(http.StatusOK)
+}
+
+// @Summary Destroy SecurityRule to SecurityGroup
+// @Description Destroy SecurityRule to SecurityGroup
+// @Tags SecurityGroup
+// @Accept json
+// @Produce json
+// @Param id path string true "id"
+// @Param security_rule_id path string true "security rule id"
+// @Success 200
+// @Failure 400
+// @Failure 404
+// @Failure 500
+// @Router /security-groups/{id}/security-rules/{security_rule_id} [delete]
+func (h *Handlers) DestroySecurityRuleToSecurityGroup(ctx *gin.Context) {
+ var params types.AddSecurityRuleToSecurityGroupParams
+ if err := ctx.ShouldBindUri(¶ms); err != nil {
+ ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
+ return
+ }
+
+ err := h.service.DestroySecurityRuleToSecurityGroup(ctx.Request.Context(), params.ID, params.SecurityRuleID)
+ if err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ ctx.Status(http.StatusOK)
+}
diff --git a/manager/handlers/security_rule.go b/manager/handlers/security_rule.go
new file mode 100644
index 000000000..706999de2
--- /dev/null
+++ b/manager/handlers/security_rule.go
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2020 The Dragonfly Authors
+ *
+ * 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 handlers
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+
+ // nolint
+ _ "d7y.io/dragonfly/v2/manager/model"
+ "d7y.io/dragonfly/v2/manager/types"
+)
+
+// @Summary Create SecurityRule
+// @Description create by json config
+// @Tags SecurityRule
+// @Accept json
+// @Produce json
+// @Param SecurityRule body types.CreateSecurityRuleRequest true "SecurityRule"
+// @Success 200 {object} model.SecurityRule
+// @Failure 400
+// @Failure 404
+// @Failure 500
+// @Router /security-rules [post]
+func (h *Handlers) CreateSecurityRule(ctx *gin.Context) {
+ var json types.CreateSecurityRuleRequest
+ if err := ctx.ShouldBindJSON(&json); err != nil {
+ ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
+ return
+ }
+
+ securityRule, err := h.service.CreateSecurityRule(ctx.Request.Context(), json)
+ if err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ ctx.JSON(http.StatusOK, securityRule)
+}
+
+// @Summary Destroy SecurityRule
+// @Description Destroy by id
+// @Tags SecurityRule
+// @Accept json
+// @Produce json
+// @Param id path string true "id"
+// @Success 200
+// @Failure 400
+// @Failure 404
+// @Failure 500
+// @Router /securityRules/{id} [delete]
+func (h *Handlers) DestroySecurityRule(ctx *gin.Context) {
+ var params types.SecurityRuleParams
+ if err := ctx.ShouldBindUri(¶ms); err != nil {
+ ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
+ return
+ }
+
+ if err := h.service.DestroySecurityRule(ctx.Request.Context(), params.ID); err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ ctx.Status(http.StatusOK)
+}
+
+// @Summary Update SecurityRule
+// @Description Update by json config
+// @Tags SecurityRule
+// @Accept json
+// @Produce json
+// @Param id path string true "id"
+// @Param SecurityRule body types.UpdateSecurityRuleRequest true "SecurityRule"
+// @Success 200 {object} model.SecurityRule
+// @Failure 400
+// @Failure 404
+// @Failure 500
+// @Router /security-rules/{id} [patch]
+func (h *Handlers) UpdateSecurityRule(ctx *gin.Context) {
+ var params types.SecurityRuleParams
+ if err := ctx.ShouldBindUri(¶ms); err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ var json types.UpdateSecurityRuleRequest
+ if err := ctx.ShouldBindJSON(&json); err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ securityRule, err := h.service.UpdateSecurityRule(ctx.Request.Context(), params.ID, json)
+ if err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ ctx.JSON(http.StatusOK, securityRule)
+}
+
+// @Summary Get SecurityRule
+// @Description Get SecurityRule by id
+// @Tags SecurityRule
+// @Accept json
+// @Produce json
+// @Param id path string true "id"
+// @Success 200 {object} model.SecurityRule
+// @Failure 400
+// @Failure 404
+// @Failure 500
+// @Router /security-rules/{id} [get]
+func (h *Handlers) GetSecurityRule(ctx *gin.Context) {
+ var params types.SecurityRuleParams
+ if err := ctx.ShouldBindUri(¶ms); err != nil {
+ ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
+ return
+ }
+
+ securityRule, err := h.service.GetSecurityRule(ctx.Request.Context(), params.ID)
+ if err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ ctx.JSON(http.StatusOK, securityRule)
+}
+
+// @Summary Get SecurityRules
+// @Description Get SecurityRules
+// @Tags SecurityRule
+// @Accept json
+// @Produce json
+// @Param page query int true "current page" default(0)
+// @Param per_page query int true "return max item count, default 10, max 50" default(10) minimum(2) maximum(50)
+// @Success 200 {object} []model.SecurityRule
+// @Failure 400
+// @Failure 404
+// @Failure 500
+// @Router /security-rules [get]
+func (h *Handlers) GetSecurityRules(ctx *gin.Context) {
+ var query types.GetSecurityRulesQuery
+ if err := ctx.ShouldBindQuery(&query); err != nil {
+ ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
+ return
+ }
+
+ h.setPaginationDefault(&query.Page, &query.PerPage)
+ securityRules, count, err := h.service.GetSecurityRules(ctx.Request.Context(), query)
+ if err != nil {
+ ctx.Error(err) // nolint: errcheck
+ return
+ }
+
+ h.setPaginationLinkHeader(ctx, query.Page, query.PerPage, int(count))
+ ctx.JSON(http.StatusOK, securityRules)
+}
diff --git a/manager/model/security_group.go b/manager/model/security_group.go
index fb9269475..bca3d3830 100644
--- a/manager/model/security_group.go
+++ b/manager/model/security_group.go
@@ -20,8 +20,7 @@ type SecurityGroup struct {
Model
Name string `gorm:"column:name;type:varchar(256);index:uk_security_group_name,unique;not null;comment:name" json:"name"`
BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"`
- Domain string `gorm:"column:domain;type:varchar(256);index:uk_security_group_domain,unique;not null;comment:domain" json:"domain"`
- ProxyDomain string `gorm:"column:proxy_domain;type:varchar(1024);comment:proxy domain" json:"proxy_domain"`
+ SecurityRules []SecurityRule `gorm:"many2many:security_group_security_rule;" json:"security_rules"`
SchedulerClusters []SchedulerCluster `json:"-"`
CDNClusters []CDNCluster `json:"-"`
}
diff --git a/manager/model/security_rule.go b/manager/model/security_rule.go
new file mode 100644
index 000000000..256d46a30
--- /dev/null
+++ b/manager/model/security_rule.go
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 The Dragonfly Authors
+ *
+ * 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 model
+
+type SecurityRule struct {
+ Model
+ Name string `gorm:"column:name;type:varchar(256);index:uk_security_rule_name,unique;not null;comment:name" json:"name"`
+ BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"`
+ Domain string `gorm:"column:domain;type:varchar(256);index:uk_security_rule_domain,unique;not null;comment:domain" json:"domain"`
+ ProxyDomain string `gorm:"column:proxy_domain;type:varchar(1024);comment:proxy domain" json:"proxy_domain"`
+ SecurityGroups []SecurityGroup `gorm:"many2many:security_group_security_rule;" json:"security_groups"`
+}
diff --git a/manager/router/router.go b/manager/router/router.go
index 12d506bf3..7f273aea6 100644
--- a/manager/router/router.go
+++ b/manager/router/router.go
@@ -165,6 +165,14 @@ func Init(cfg *config.Config, service service.REST, enforcer *casbin.Enforcer) (
c.GET(":id", h.GetCDN)
c.GET("", h.GetCDNs)
+ // Security Rule
+ sr := apiv1.Group("/security-rules", jwt.MiddlewareFunc(), rbac)
+ sr.POST("", h.CreateSecurityRule)
+ sr.DELETE(":id", h.DestroySecurityRule)
+ sr.PATCH(":id", h.UpdateSecurityRule)
+ sr.GET(":id", h.GetSecurityRule)
+ sr.GET("", h.GetSecurityRules)
+
// Security Group
sg := apiv1.Group("/security-groups", jwt.MiddlewareFunc(), rbac)
sg.POST("", h.CreateSecurityGroup)
@@ -174,6 +182,8 @@ func Init(cfg *config.Config, service service.REST, enforcer *casbin.Enforcer) (
sg.GET("", h.GetSecurityGroups)
sg.PUT(":id/scheduler-clusters/:scheduler_cluster_id", h.AddSchedulerClusterToSecurityGroup)
sg.PUT(":id/cdn-clusters/:cdn_cluster_id", h.AddCDNClusterToSecurityGroup)
+ sg.PUT(":id/security-rules/:security_rule_id", h.AddSecurityRuleToSecurityGroup)
+ sg.DELETE(":id/security-rules/:security_rule_id", h.DestroySecurityRuleToSecurityGroup)
// Config
config := apiv1.Group("/configs")
diff --git a/manager/searcher/searcher.go b/manager/searcher/searcher.go
index 8deeec52d..50e954541 100644
--- a/manager/searcher/searcher.go
+++ b/manager/searcher/searcher.go
@@ -17,28 +17,56 @@
package searcher
import (
- "sort"
+ "strings"
"github.com/mitchellh/mapstructure"
- "gonum.org/v1/gonum/stat"
"d7y.io/dragonfly/v2/manager/model"
+ "d7y.io/dragonfly/v2/pkg/util/mathutils"
)
const (
+ // Condition IDC key
+ conditionIDC = "idc"
+
+ // Condition location key
+ conditionLocation = "location"
+
+ // Condition netTopology key
+ conditionNetTopology = "net_topology"
+
+ // Condition security domain key
conditionSecurityDomain = "security_domain"
- conditionLocation = "location"
- conditionIDC = "idc"
)
const (
- conditionLocationWeight = 0.7
- conditionIDCWeight = 0.3
+ // IDC affinity weight
+ idcAffinityWeight float64 = 0.5
+
+ // NetTopology affinity weight
+ netTopologyAffinityWeight = 0.3
+
+ // Location affinity weight
+ locationAffinityWeight = 0.2
+)
+
+const (
+ // Maximum score
+ maxScore float64 = 1.0
+
+ // Minimum score
+ minScore = 0
+)
+
+const (
+ // Maximum number of elements
+ maxElementLen = 5
)
type Scopes struct {
- Location []string `mapstructure:"location"`
- IDC []string `mapstructure:"idc"`
+ IDC string `mapstructure:"idc"`
+ Location string `mapstructure:"location"`
+ NetTopology string `mapstructure:"net_topology"`
}
type Searcher interface {
@@ -62,63 +90,96 @@ func (s *searcher) FindSchedulerCluster(schedulerClusters []model.SchedulerClust
}
// If there are security domain conditions, match clusters of the same security domain.
- // If the security domain condition does not exist, it matches clusters that does not have a security domain.
+ // If the security domain condition does not exist, it will match all scheduler security domains.
// Then use clusters sets to score according to scopes.
- securityDomain := conditions[conditionSecurityDomain]
var clusters []model.SchedulerCluster
- for _, v := range schedulerClusters {
- if v.SecurityGroup.Domain == securityDomain {
- clusters = append(clusters, v)
+ securityDomain := conditions[conditionSecurityDomain]
+ for _, schedulerCluster := range schedulerClusters {
+ if len(schedulerCluster.Schedulers) > 0 {
+ if securityDomain == "" {
+ clusters = append(clusters, schedulerCluster)
+ } else {
+ for _, securityRule := range schedulerCluster.SecurityGroup.SecurityRules {
+ if strings.Compare(securityRule.Domain, securityDomain) == 0 {
+ clusters = append(clusters, schedulerCluster)
+ }
+ }
+ }
}
}
switch len(clusters) {
case 0:
+ // If the security domain does not match, there is no cluster available
return model.SchedulerCluster{}, false
case 1:
+ // If only one cluster matches the security domain, return the cluster directly
return clusters[0], true
default:
- var maxMean float64 = 0
- cluster := clusters[0]
- for _, v := range clusters {
- mean := calculateSchedulerClusterMean(conditions, v.Scopes)
- if mean > maxMean {
- maxMean = mean
- cluster = v
+ // If there are multiple clusters matching the security domain,
+ // select the schuelder cluster with a higher score
+ var maxScore float64 = 0
+ result := clusters[0]
+ for _, cluster := range clusters {
+ var scopes Scopes
+ if err := mapstructure.Decode(cluster.Scopes, &scopes); err != nil {
+ // Scopes parse failed to skip this evaluation
+ continue
+ }
+
+ score := evaluate(conditions, scopes)
+ if score > maxScore {
+ maxScore = score
+ result = cluster
}
}
- return cluster, true
+ return result, true
}
}
-func calculateSchedulerClusterMean(conditions map[string]string, rawScopes map[string]interface{}) float64 {
- var scopes Scopes
- if err := mapstructure.Decode(rawScopes, &scopes); err != nil {
- return 0
- }
-
- location := conditions[conditionLocation]
- lx := calculateConditionScore(location, scopes.Location)
+// Evaluate the degree of matching between scheduler cluster and dfdaemon
+func evaluate(conditions map[string]string, scopes Scopes) float64 {
+ return idcAffinityWeight*calculateIDCAffinityScore(conditions[conditionIDC], scopes.IDC) +
+ locationAffinityWeight*calculateMultiElementAffinityScore(conditions[conditionLocation], scopes.Location) +
+ netTopologyAffinityWeight*calculateMultiElementAffinityScore(conditions[conditionNetTopology], scopes.NetTopology)
+}
- idc := conditions[conditionIDC]
- ix := calculateConditionScore(idc, scopes.IDC)
+// calculateIDCAffinityScore 0.0~1.0 larger and better
+func calculateIDCAffinityScore(dst, src string) float64 {
+ if dst != "" && src != "" && strings.Compare(dst, src) == 0 {
+ return maxScore
+ }
- return stat.Mean([]float64{lx, ix}, []float64{conditionLocationWeight, conditionIDCWeight})
+ return minScore
}
-func calculateConditionScore(value string, scope []string) float64 {
- if value == "" {
- return 0
+// calculateMultiElementAffinityScore 0.0~1.0 larger and better
+func calculateMultiElementAffinityScore(dst, src string) float64 {
+ if dst == "" || src == "" {
+ return minScore
+ }
+
+ if strings.Compare(dst, src) == 0 {
+ return maxScore
}
- if len(scope) <= 0 {
- return 0
+ // Calculate the number of multi-element matches divided by "|"
+ var score, elementLen int
+ dstElements := strings.Split(dst, "|")
+ srcElements := strings.Split(src, "|")
+ elementLen = mathutils.MaxInt(len(dstElements), len(srcElements))
+
+ // Maximum element length is 5
+ if elementLen > maxElementLen {
+ elementLen = maxElementLen
}
- i := sort.SearchStrings(scope, value)
- if i < 0 {
- return 0
+ for i := 0; i < elementLen; i++ {
+ if strings.Compare(dstElements[i], srcElements[i]) != 0 {
+ break
+ }
+ score++
}
- return 1
+ return float64(score) / float64(maxElementLen)
}
diff --git a/manager/searcher/searcher_test.go b/manager/searcher/searcher_test.go
index a4c9e0709..b9c67e430 100644
--- a/manager/searcher/searcher_test.go
+++ b/manager/searcher/searcher_test.go
@@ -55,7 +55,17 @@ func TestSchedulerCluster(t *testing.T) {
{
Name: "foo",
SecurityGroup: model.SecurityGroup{
- Domain: "domain-1",
+ SecurityRules: []model.SecurityRule{
+ {
+ Domain: "domain-1",
+ },
+ },
+ },
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
},
},
{
@@ -77,9 +87,21 @@ func TestSchedulerCluster(t *testing.T) {
Scopes: map[string]interface{}{
"location": []string{"location-1"},
},
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
+ },
},
{
Name: "bar",
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "bar",
+ Status: "active",
+ },
+ },
},
},
conditions: map[string]string{"location": "location-1"},
@@ -97,9 +119,21 @@ func TestSchedulerCluster(t *testing.T) {
Scopes: map[string]interface{}{
"idc": []string{"idc-1"},
},
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
+ },
},
{
Name: "bar",
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "bar",
+ Status: "active",
+ },
+ },
},
},
conditions: map[string]string{"idc": "idc-1"},
@@ -109,6 +143,38 @@ func TestSchedulerCluster(t *testing.T) {
assert.Equal(ok, true)
},
},
+ {
+ name: "match according to net topology condition",
+ schedulerClusters: []model.SchedulerCluster{
+ {
+ Name: "foo",
+ Scopes: map[string]interface{}{
+ "net_topology": []string{"net-topology-1"},
+ },
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
+ },
+ },
+ {
+ Name: "bar",
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "bar",
+ Status: "active",
+ },
+ },
+ },
+ },
+ conditions: map[string]string{"net_topology": "net-topology-1"},
+ expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+ assert := assert.New(t)
+ assert.Equal(data.Name, "foo")
+ assert.Equal(ok, true)
+ },
+ },
{
name: "match according to location and idc condition",
schedulerClusters: []model.SchedulerCluster{
@@ -118,9 +184,21 @@ func TestSchedulerCluster(t *testing.T) {
"location": []string{"location-1"},
"idc": []string{"idc-1"},
},
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
+ },
},
{
Name: "bar",
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "bar",
+ Status: "active",
+ },
+ },
},
},
conditions: map[string]string{
@@ -142,11 +220,27 @@ func TestSchedulerCluster(t *testing.T) {
"location": []string{"location-1"},
},
SecurityGroup: model.SecurityGroup{
- Domain: "domain-1",
+ SecurityRules: []model.SecurityRule{
+ {
+ Domain: "domain-1",
+ },
+ },
+ },
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
},
},
{
Name: "bar",
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "bar",
+ Status: "active",
+ },
+ },
},
},
conditions: map[string]string{
@@ -168,11 +262,27 @@ func TestSchedulerCluster(t *testing.T) {
"idc": []string{"idc-1"},
},
SecurityGroup: model.SecurityGroup{
- Domain: "domain-1",
+ SecurityRules: []model.SecurityRule{
+ {
+ Domain: "domain-1",
+ },
+ },
+ },
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
},
},
{
Name: "bar",
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "bar",
+ Status: "active",
+ },
+ },
},
},
conditions: map[string]string{
@@ -195,11 +305,27 @@ func TestSchedulerCluster(t *testing.T) {
"location": []string{"location-1"},
},
SecurityGroup: model.SecurityGroup{
- Domain: "domain-1",
+ SecurityRules: []model.SecurityRule{
+ {
+ Domain: "domain-1",
+ },
+ },
+ },
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "foo",
+ Status: "active",
+ },
},
},
{
Name: "bar",
+ Schedulers: []model.Scheduler{
+ {
+ HostName: "bar",
+ Status: "active",
+ },
+ },
},
},
conditions: map[string]string{
@@ -223,127 +349,3 @@ func TestSchedulerCluster(t *testing.T) {
})
}
}
-
-func TestCalculateSchedulerClusterMean(t *testing.T) {
- tests := []struct {
- name string
- conditions map[string]string
- rawScopes map[string]interface{}
- expect func(t *testing.T, mean float64)
- }{
- {
- name: "conditions and rawScopes is empty",
- conditions: map[string]string{},
- rawScopes: map[string]interface{}{},
- expect: func(t *testing.T, mean float64) {
- assert := assert.New(t)
- assert.Equal(mean, float64(0))
- },
- },
- {
- name: "missed matches",
- conditions: map[string]string{
- "location": "location-1",
- },
- rawScopes: map[string]interface{}{
- "idc": []string{"idc-1"},
- },
- expect: func(t *testing.T, mean float64) {
- assert := assert.New(t)
- assert.Equal(mean, float64(0))
- },
- },
- {
- name: "match according to location",
- conditions: map[string]string{
- "location": "location-1",
- },
- rawScopes: map[string]interface{}{
- "location": []string{"location-1"},
- },
- expect: func(t *testing.T, mean float64) {
- assert := assert.New(t)
- assert.Equal(mean, float64(conditionLocationWeight))
- },
- },
- {
- name: "match according to idc",
- conditions: map[string]string{
- "idc": "idc-1",
- },
- rawScopes: map[string]interface{}{
- "idc": []string{"idc-1"},
- },
- expect: func(t *testing.T, mean float64) {
- assert := assert.New(t)
- assert.Equal(mean, float64(conditionIDCWeight))
- },
- },
- {
- name: "match according to location and idc",
- conditions: map[string]string{
- "location": "location-1",
- "idc": "idc-1",
- },
- rawScopes: map[string]interface{}{
- "location": []string{"location-1"},
- "idc": []string{"idc-1"},
- },
- expect: func(t *testing.T, mean float64) {
- assert := assert.New(t)
- assert.Equal(mean, float64(conditionLocationWeight+conditionIDCWeight))
- },
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- mean := calculateSchedulerClusterMean(tc.conditions, tc.rawScopes)
- tc.expect(t, mean)
- })
- }
-}
-
-func TestCalculateConditionScore(t *testing.T) {
- tests := []struct {
- name string
- value string
- scope []string
- expect func(t *testing.T, score float64)
- }{
- {
- name: "value is empty",
- value: "",
- scope: []string{"foo"},
- expect: func(t *testing.T, score float64) {
- assert := assert.New(t)
- assert.Equal(score, float64(0))
- },
- },
- {
- name: "scope is empty",
- value: "foo",
- scope: []string{},
- expect: func(t *testing.T, score float64) {
- assert := assert.New(t)
- assert.Equal(score, float64(0))
- },
- },
- {
- name: "match according to value",
- value: "foo",
- scope: []string{"foo"},
- expect: func(t *testing.T, score float64) {
- assert := assert.New(t)
- assert.Equal(score, float64(1))
- },
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- score := calculateConditionScore(tc.value, tc.scope)
- tc.expect(t, score)
- })
- }
-}
diff --git a/manager/service/cdn_cluster.go b/manager/service/cdn_cluster.go
index 87f80452f..596475e00 100644
--- a/manager/service/cdn_cluster.go
+++ b/manager/service/cdn_cluster.go
@@ -56,33 +56,6 @@ func (s *rest) DestroyCDNCluster(ctx context.Context, id uint) error {
return nil
}
-func (s *rest) CreateCDNClusterWithSecurityGroupDomain(ctx context.Context, json types.CreateCDNClusterRequest) (*model.CDNCluster, error) {
- securityGroup := model.SecurityGroup{
- Domain: json.SecurityGroupDomain,
- }
- if err := s.db.WithContext(ctx).First(&securityGroup).Error; err != nil {
- return s.CreateCDNCluster(ctx, json)
- }
-
- config, err := structutils.StructToMap(json.Config)
- if err != nil {
- return nil, err
- }
-
- cdnCluster := model.CDNCluster{
- Name: json.Name,
- BIO: json.BIO,
- Config: config,
- }
-
- if err := s.db.WithContext(ctx).Model(&securityGroup).Association("CDNClusters").Append(&cdnCluster); err != nil {
- return nil, err
-
- }
-
- return &cdnCluster, nil
-}
-
func (s *rest) UpdateCDNCluster(ctx context.Context, id uint, json types.UpdateCDNClusterRequest) (*model.CDNCluster, error) {
config, err := structutils.StructToMap(json.Config)
if err != nil {
@@ -101,32 +74,6 @@ func (s *rest) UpdateCDNCluster(ctx context.Context, id uint, json types.UpdateC
return &cdnCluster, nil
}
-func (s *rest) UpdateCDNClusterWithSecurityGroupDomain(ctx context.Context, id uint, json types.UpdateCDNClusterRequest) (*model.CDNCluster, error) {
- securityGroup := model.SecurityGroup{
- Domain: json.SecurityGroupDomain,
- }
- if err := s.db.WithContext(ctx).First(&securityGroup).Error; err != nil {
- return s.UpdateCDNCluster(ctx, id, json)
- }
-
- config, err := structutils.StructToMap(json.Config)
- if err != nil {
- return nil, err
- }
-
- cdnCluster := model.CDNCluster{
- Name: json.Name,
- BIO: json.BIO,
- Config: config,
- }
-
- if err := s.db.WithContext(ctx).Model(&securityGroup).Association("CDNClusters").Append(&cdnCluster); err != nil {
- return nil, err
- }
-
- return &cdnCluster, nil
-}
-
func (s *rest) GetCDNCluster(ctx context.Context, id uint) (*model.CDNCluster, error) {
cdnCluster := model.CDNCluster{}
if err := s.db.WithContext(ctx).First(&cdnCluster, id).Error; err != nil {
diff --git a/manager/service/scheduler_cluster.go b/manager/service/scheduler_cluster.go
index a77fe3746..247ff31e9 100644
--- a/manager/service/scheduler_cluster.go
+++ b/manager/service/scheduler_cluster.go
@@ -62,51 +62,6 @@ func (s *rest) CreateSchedulerCluster(ctx context.Context, json types.CreateSche
return &schedulerCluster, nil
}
-func (s *rest) CreateSchedulerClusterWithSecurityGroupDomain(ctx context.Context, json types.CreateSchedulerClusterRequest) (*model.SchedulerCluster, error) {
- securityGroup := model.SecurityGroup{
- Domain: json.SecurityGroupDomain,
- }
- if err := s.db.WithContext(ctx).First(&securityGroup).Error; err != nil {
- return s.CreateSchedulerCluster(ctx, json)
- }
-
- config, err := structutils.StructToMap(json.Config)
- if err != nil {
- return nil, err
- }
-
- clientConfig, err := structutils.StructToMap(json.ClientConfig)
- if err != nil {
- return nil, err
- }
-
- scopes, err := structutils.StructToMap(json.Scopes)
- if err != nil {
- return nil, err
- }
-
- schedulerCluster := model.SchedulerCluster{
- Name: json.Name,
- BIO: json.BIO,
- Config: config,
- ClientConfig: clientConfig,
- Scopes: scopes,
- IsDefault: json.IsDefault,
- }
-
- if err := s.db.WithContext(ctx).Model(&securityGroup).Association("SchedulerClusters").Append(&schedulerCluster); err != nil {
- return nil, err
- }
-
- if json.CDNClusterID > 0 {
- if err := s.AddSchedulerClusterToCDNCluster(ctx, json.CDNClusterID, schedulerCluster.ID); err != nil {
- return nil, err
- }
- }
-
- return &schedulerCluster, nil
-}
-
func (s *rest) DestroySchedulerCluster(ctx context.Context, id uint) error {
schedulerCluster := model.SchedulerCluster{}
if err := s.db.WithContext(ctx).First(&schedulerCluster, id).Error; err != nil {
@@ -157,51 +112,6 @@ func (s *rest) UpdateSchedulerCluster(ctx context.Context, id uint, json types.U
return &schedulerCluster, nil
}
-func (s *rest) UpdateSchedulerClusterWithSecurityGroupDomain(ctx context.Context, id uint, json types.UpdateSchedulerClusterRequest) (*model.SchedulerCluster, error) {
- securityGroup := model.SecurityGroup{
- Domain: json.SecurityGroupDomain,
- }
- if err := s.db.WithContext(ctx).First(&securityGroup).Error; err != nil {
- return s.UpdateSchedulerCluster(ctx, id, json)
- }
-
- config, err := structutils.StructToMap(json.Config)
- if err != nil {
- return nil, err
- }
-
- clientConfig, err := structutils.StructToMap(json.ClientConfig)
- if err != nil {
- return nil, err
- }
-
- scopes, err := structutils.StructToMap(json.Scopes)
- if err != nil {
- return nil, err
- }
-
- schedulerCluster := model.SchedulerCluster{
- Name: json.Name,
- BIO: json.BIO,
- Config: config,
- ClientConfig: clientConfig,
- Scopes: scopes,
- IsDefault: json.IsDefault,
- }
-
- if err := s.db.WithContext(ctx).Model(&securityGroup).Association("SchedulerClusters").Append(&schedulerCluster); err != nil {
- return nil, err
- }
-
- if json.CDNClusterID > 0 {
- if err := s.AddSchedulerClusterToCDNCluster(ctx, json.CDNClusterID, schedulerCluster.ID); err != nil {
- return nil, err
- }
- }
-
- return &schedulerCluster, nil
-}
-
func (s *rest) GetSchedulerCluster(ctx context.Context, id uint) (*model.SchedulerCluster, error) {
schedulerCluster := model.SchedulerCluster{}
if err := s.db.WithContext(ctx).Preload("CDNClusters").First(&schedulerCluster, id).Error; err != nil {
diff --git a/manager/service/security_group.go b/manager/service/security_group.go
index 635438a75..f0788b1ef 100644
--- a/manager/service/security_group.go
+++ b/manager/service/security_group.go
@@ -25,10 +25,8 @@ import (
func (s *rest) CreateSecurityGroup(ctx context.Context, json types.CreateSecurityGroupRequest) (*model.SecurityGroup, error) {
securityGroup := model.SecurityGroup{
- Name: json.Name,
- BIO: json.BIO,
- Domain: json.Domain,
- ProxyDomain: json.ProxyDomain,
+ Name: json.Name,
+ BIO: json.BIO,
}
if err := s.db.WithContext(ctx).Create(&securityGroup).Error; err != nil {
@@ -54,10 +52,8 @@ func (s *rest) DestroySecurityGroup(ctx context.Context, id uint) error {
func (s *rest) UpdateSecurityGroup(ctx context.Context, id uint, json types.UpdateSecurityGroupRequest) (*model.SecurityGroup, error) {
securityGroup := model.SecurityGroup{}
if err := s.db.WithContext(ctx).First(&securityGroup, id).Updates(model.SecurityGroup{
- Name: json.Name,
- BIO: json.BIO,
- Domain: json.Domain,
- ProxyDomain: json.ProxyDomain,
+ Name: json.Name,
+ BIO: json.BIO,
}).Error; err != nil {
return nil, err
}
@@ -67,7 +63,7 @@ func (s *rest) UpdateSecurityGroup(ctx context.Context, id uint, json types.Upda
func (s *rest) GetSecurityGroup(ctx context.Context, id uint) (*model.SecurityGroup, error) {
securityGroup := model.SecurityGroup{}
- if err := s.db.WithContext(ctx).First(&securityGroup, id).Error; err != nil {
+ if err := s.db.WithContext(ctx).Preload("SecurityRules").First(&securityGroup, id).Error; err != nil {
return nil, err
}
@@ -78,9 +74,8 @@ func (s *rest) GetSecurityGroups(ctx context.Context, q types.GetSecurityGroupsQ
var count int64
var securityGroups []model.SecurityGroup
if err := s.db.WithContext(ctx).Scopes(model.Paginate(q.Page, q.PerPage)).Where(&model.SecurityGroup{
- Name: q.Name,
- Domain: q.Domain,
- }).Find(&securityGroups).Count(&count).Error; err != nil {
+ Name: q.Name,
+ }).Preload("SecurityRules").Find(&securityGroups).Count(&count).Error; err != nil {
return nil, 0, err
}
@@ -122,3 +117,39 @@ func (s *rest) AddCDNClusterToSecurityGroup(ctx context.Context, id, cdnClusterI
return nil
}
+
+func (s *rest) AddSecurityRuleToSecurityGroup(ctx context.Context, id, securityRuleID uint) error {
+ securityGroup := model.SecurityGroup{}
+ if err := s.db.WithContext(ctx).First(&securityGroup, id).Error; err != nil {
+ return err
+ }
+
+ securityRule := model.SecurityRule{}
+ if err := s.db.WithContext(ctx).First(&securityRule, securityRuleID).Error; err != nil {
+ return err
+ }
+
+ if err := s.db.WithContext(ctx).Model(&securityGroup).Association("SecurityRules").Append(&securityRule); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (s *rest) DestroySecurityRuleToSecurityGroup(ctx context.Context, id, securityRuleID uint) error {
+ securityGroup := model.SecurityGroup{}
+ if err := s.db.WithContext(ctx).First(&securityGroup, id).Error; err != nil {
+ return err
+ }
+
+ securityRule := model.SecurityRule{}
+ if err := s.db.WithContext(ctx).First(&securityRule, securityRuleID).Error; err != nil {
+ return err
+ }
+
+ if err := s.db.WithContext(ctx).Model(&securityGroup).Association("SecurityRules").Delete(&securityRule); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/manager/service/security_rule.go b/manager/service/security_rule.go
new file mode 100644
index 000000000..0cf8a6a15
--- /dev/null
+++ b/manager/service/security_rule.go
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2020 The Dragonfly Authors
+ *
+ * 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 service
+
+import (
+ "context"
+
+ "d7y.io/dragonfly/v2/manager/model"
+ "d7y.io/dragonfly/v2/manager/types"
+)
+
+func (s *rest) CreateSecurityRule(ctx context.Context, json types.CreateSecurityRuleRequest) (*model.SecurityRule, error) {
+ securityRule := model.SecurityRule{
+ Name: json.Name,
+ BIO: json.BIO,
+ Domain: json.Domain,
+ ProxyDomain: json.ProxyDomain,
+ }
+
+ if err := s.db.WithContext(ctx).Create(&securityRule).Error; err != nil {
+ return nil, err
+ }
+
+ return &securityRule, nil
+}
+
+func (s *rest) DestroySecurityRule(ctx context.Context, id uint) error {
+ securityRule := model.SecurityRule{}
+ if err := s.db.WithContext(ctx).First(&securityRule, id).Error; err != nil {
+ return err
+ }
+
+ if err := s.db.WithContext(ctx).Unscoped().Delete(&model.SecurityRule{}, id).Error; err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (s *rest) UpdateSecurityRule(ctx context.Context, id uint, json types.UpdateSecurityRuleRequest) (*model.SecurityRule, error) {
+ securityRule := model.SecurityRule{}
+ if err := s.db.WithContext(ctx).First(&securityRule, id).Updates(model.SecurityRule{
+ Name: json.Name,
+ BIO: json.BIO,
+ Domain: json.Domain,
+ ProxyDomain: json.ProxyDomain,
+ }).Error; err != nil {
+ return nil, err
+ }
+
+ return &securityRule, nil
+}
+
+func (s *rest) GetSecurityRule(ctx context.Context, id uint) (*model.SecurityRule, error) {
+ securityRule := model.SecurityRule{}
+ if err := s.db.WithContext(ctx).First(&securityRule, id).Error; err != nil {
+ return nil, err
+ }
+
+ return &securityRule, nil
+}
+
+func (s *rest) GetSecurityRules(ctx context.Context, q types.GetSecurityRulesQuery) (*[]model.SecurityRule, int64, error) {
+ var count int64
+ var securityRules []model.SecurityRule
+ if err := s.db.WithContext(ctx).Scopes(model.Paginate(q.Page, q.PerPage)).Where(&model.SecurityRule{
+ Name: q.Name,
+ }).Find(&securityRules).Count(&count).Error; err != nil {
+ return nil, 0, err
+ }
+
+ return &securityRules, count, nil
+}
diff --git a/manager/service/service.go b/manager/service/service.go
index c1dfaa18b..63b8c1904 100644
--- a/manager/service/service.go
+++ b/manager/service/service.go
@@ -60,10 +60,8 @@ type REST interface {
GetOauths(context.Context, types.GetOauthsQuery) (*[]model.Oauth, int64, error)
CreateCDNCluster(context.Context, types.CreateCDNClusterRequest) (*model.CDNCluster, error)
- CreateCDNClusterWithSecurityGroupDomain(context.Context, types.CreateCDNClusterRequest) (*model.CDNCluster, error)
DestroyCDNCluster(context.Context, uint) error
UpdateCDNCluster(context.Context, uint, types.UpdateCDNClusterRequest) (*model.CDNCluster, error)
- UpdateCDNClusterWithSecurityGroupDomain(context.Context, uint, types.UpdateCDNClusterRequest) (*model.CDNCluster, error)
GetCDNCluster(context.Context, uint) (*model.CDNCluster, error)
GetCDNClusters(context.Context, types.GetCDNClustersQuery) (*[]model.CDNCluster, int64, error)
AddCDNToCDNCluster(context.Context, uint, uint) error
@@ -76,10 +74,8 @@ type REST interface {
GetCDNs(context.Context, types.GetCDNsQuery) (*[]model.CDN, int64, error)
CreateSchedulerCluster(context.Context, types.CreateSchedulerClusterRequest) (*model.SchedulerCluster, error)
- CreateSchedulerClusterWithSecurityGroupDomain(context.Context, types.CreateSchedulerClusterRequest) (*model.SchedulerCluster, error)
DestroySchedulerCluster(context.Context, uint) error
UpdateSchedulerCluster(context.Context, uint, types.UpdateSchedulerClusterRequest) (*model.SchedulerCluster, error)
- UpdateSchedulerClusterWithSecurityGroupDomain(context.Context, uint, types.UpdateSchedulerClusterRequest) (*model.SchedulerCluster, error)
GetSchedulerCluster(context.Context, uint) (*model.SchedulerCluster, error)
GetSchedulerClusters(context.Context, types.GetSchedulerClustersQuery) (*[]model.SchedulerCluster, int64, error)
AddSchedulerToSchedulerCluster(context.Context, uint, uint) error
@@ -90,6 +86,12 @@ type REST interface {
GetScheduler(context.Context, uint) (*model.Scheduler, error)
GetSchedulers(context.Context, types.GetSchedulersQuery) (*[]model.Scheduler, int64, error)
+ CreateSecurityRule(context.Context, types.CreateSecurityRuleRequest) (*model.SecurityRule, error)
+ DestroySecurityRule(context.Context, uint) error
+ UpdateSecurityRule(context.Context, uint, types.UpdateSecurityRuleRequest) (*model.SecurityRule, error)
+ GetSecurityRule(context.Context, uint) (*model.SecurityRule, error)
+ GetSecurityRules(context.Context, types.GetSecurityRulesQuery) (*[]model.SecurityRule, int64, error)
+
CreateSecurityGroup(context.Context, types.CreateSecurityGroupRequest) (*model.SecurityGroup, error)
DestroySecurityGroup(context.Context, uint) error
UpdateSecurityGroup(context.Context, uint, types.UpdateSecurityGroupRequest) (*model.SecurityGroup, error)
@@ -97,6 +99,8 @@ type REST interface {
GetSecurityGroups(context.Context, types.GetSecurityGroupsQuery) (*[]model.SecurityGroup, int64, error)
AddSchedulerClusterToSecurityGroup(context.Context, uint, uint) error
AddCDNClusterToSecurityGroup(context.Context, uint, uint) error
+ AddSecurityRuleToSecurityGroup(context.Context, uint, uint) error
+ DestroySecurityRuleToSecurityGroup(context.Context, uint, uint) error
CreateConfig(context.Context, types.CreateConfigRequest) (*model.Config, error)
DestroyConfig(context.Context, uint) error
diff --git a/manager/service/service_grpc.go b/manager/service/service_grpc.go
index d09e739d0..28b94be55 100644
--- a/manager/service/service_grpc.go
+++ b/manager/service/service_grpc.go
@@ -66,7 +66,7 @@ func (s *GRPC) GetCDN(ctx context.Context, req *manager.GetCDNRequest) (*manager
// Cache Miss
logger.Infof("%s cache miss", cacheKey)
cdn := model.CDN{}
- if err := s.db.WithContext(ctx).Preload("CDNCluster.SecurityGroup").First(&cdn, &model.CDN{
+ if err := s.db.WithContext(ctx).Preload("CDNCluster").First(&cdn, &model.CDN{
HostName: req.HostName,
CDNClusterID: uint(req.CdnClusterId),
}).Error; err != nil {
@@ -93,13 +93,6 @@ func (s *GRPC) GetCDN(ctx context.Context, req *manager.GetCDNRequest) (*manager
Name: cdn.CDNCluster.Name,
Bio: cdn.CDNCluster.BIO,
Config: config,
- SecurityGroup: &manager.SecurityGroup{
- Id: uint64(cdn.CDNCluster.SecurityGroup.ID),
- Name: cdn.CDNCluster.SecurityGroup.Name,
- Bio: cdn.CDNCluster.SecurityGroup.BIO,
- Domain: cdn.CDNCluster.SecurityGroup.Domain,
- ProxyDomain: cdn.CDNCluster.SecurityGroup.ProxyDomain,
- },
},
}
@@ -197,7 +190,7 @@ func (s *GRPC) GetScheduler(ctx context.Context, req *manager.GetSchedulerReques
// Cache Miss
logger.Infof("%s cache miss", cacheKey)
scheduler := model.Scheduler{}
- if err := s.db.WithContext(ctx).Preload("SchedulerCluster.SecurityGroup").Preload("SchedulerCluster.CDNClusters.CDNs", &model.CDN{
+ if err := s.db.WithContext(ctx).Preload("SchedulerCluster").Preload("SchedulerCluster.CDNClusters.CDNs", &model.CDN{
Status: model.CDNStatusActive,
}).First(&scheduler, &model.Scheduler{
HostName: req.HostName,
@@ -266,13 +259,6 @@ func (s *GRPC) GetScheduler(ctx context.Context, req *manager.GetSchedulerReques
Bio: scheduler.SchedulerCluster.BIO,
Config: schedulerClusterConfig,
ClientConfig: schedulerClusterClientConfig,
- SecurityGroup: &manager.SecurityGroup{
- Id: uint64(scheduler.SchedulerCluster.SecurityGroup.ID),
- Name: scheduler.SchedulerCluster.SecurityGroup.Name,
- Bio: scheduler.SchedulerCluster.SecurityGroup.BIO,
- Domain: scheduler.SchedulerCluster.SecurityGroup.Domain,
- ProxyDomain: scheduler.SchedulerCluster.SecurityGroup.ProxyDomain,
- },
},
Cdns: pbCDNs,
}
@@ -391,7 +377,7 @@ func (s *GRPC) ListSchedulers(ctx context.Context, req *manager.ListSchedulersRe
// Cache Miss
logger.Infof("%s cache miss", cacheKey)
var schedulerClusters []model.SchedulerCluster
- if err := s.db.WithContext(ctx).Preload("SecurityGroup").Find(&schedulerClusters).Error; err != nil {
+ if err := s.db.WithContext(ctx).Preload("SecurityGroup.SecurityRules").Preload("Schedulers", "status = ?", "active").Find(&schedulerClusters).Error; err != nil {
return nil, status.Error(codes.Unknown, err.Error())
}
diff --git a/manager/types/cdn_cluster.go b/manager/types/cdn_cluster.go
index 33c9379b0..07ce8e6ec 100644
--- a/manager/types/cdn_cluster.go
+++ b/manager/types/cdn_cluster.go
@@ -31,17 +31,15 @@ type AddSchedulerClusterToCDNClusterParams struct {
}
type CreateCDNClusterRequest struct {
- Name string `json:"name" binding:"required"`
- BIO string `json:"bio" binding:"omitempty"`
- Config *CDNClusterConfig `json:"config" binding:"required"`
- SecurityGroupDomain string `json:"security_group_domain" binding:"omitempty"`
+ Name string `json:"name" binding:"required"`
+ BIO string `json:"bio" binding:"omitempty"`
+ Config *CDNClusterConfig `json:"config" binding:"required"`
}
type UpdateCDNClusterRequest struct {
- Name string `json:"name" binding:"omitempty"`
- BIO string `json:"bio" binding:"omitempty"`
- Config *CDNClusterConfig `json:"config" binding:"omitempty"`
- SecurityGroupDomain string `json:"security_group_domain" binding:"omitempty"`
+ Name string `json:"name" binding:"omitempty"`
+ BIO string `json:"bio" binding:"omitempty"`
+ Config *CDNClusterConfig `json:"config" binding:"omitempty"`
}
type GetCDNClustersQuery struct {
diff --git a/manager/types/scheduler_cluster.go b/manager/types/scheduler_cluster.go
index 58da0b352..931222f4c 100644
--- a/manager/types/scheduler_cluster.go
+++ b/manager/types/scheduler_cluster.go
@@ -26,25 +26,23 @@ type AddSchedulerToSchedulerClusterParams struct {
}
type CreateSchedulerClusterRequest struct {
- Name string `json:"name" binding:"required"`
- BIO string `json:"bio" binding:"omitempty"`
- Config *SchedulerClusterConfig `json:"config" binding:"required"`
- ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"required"`
- Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
- IsDefault bool `json:"is_default" binding:"omitempty"`
- CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
- SecurityGroupDomain string `json:"security_group_domain" binding:"omitempty"`
+ Name string `json:"name" binding:"required"`
+ BIO string `json:"bio" binding:"omitempty"`
+ Config *SchedulerClusterConfig `json:"config" binding:"required"`
+ ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"required"`
+ Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
+ IsDefault bool `json:"is_default" binding:"omitempty"`
+ CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
}
type UpdateSchedulerClusterRequest struct {
- Name string `json:"name" binding:"omitempty"`
- BIO string `json:"bio" binding:"omitempty"`
- Config *SchedulerClusterConfig `json:"config" binding:"omitempty"`
- ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"omitempty"`
- Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
- IsDefault bool `json:"is_default" binding:"omitempty"`
- CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
- SecurityGroupDomain string `json:"security_group_domain" binding:"omitempty"`
+ Name string `json:"name" binding:"omitempty"`
+ BIO string `json:"bio" binding:"omitempty"`
+ Config *SchedulerClusterConfig `json:"config" binding:"omitempty"`
+ ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"omitempty"`
+ Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
+ IsDefault bool `json:"is_default" binding:"omitempty"`
+ CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
}
type GetSchedulerClustersQuery struct {
diff --git a/manager/types/security_group.go b/manager/types/security_group.go
index e01c4e0d3..4c9fdbcfc 100644
--- a/manager/types/security_group.go
+++ b/manager/types/security_group.go
@@ -30,23 +30,23 @@ type AddCDNClusterToSecurityGroupParams struct {
CDNClusterID uint `uri:"cdn_cluster_id" binding:"required"`
}
+type AddSecurityRuleToSecurityGroupParams struct {
+ ID uint `uri:"id" binding:"required"`
+ SecurityRuleID uint `uri:"security_rule_id" binding:"required"`
+}
+
type CreateSecurityGroupRequest struct {
- Name string `json:"name" binding:"required"`
- BIO string `json:"bio" binding:"omitempty"`
- Domain string `json:"domain" binding:"required"`
- ProxyDomain string `json:"proxy_domain" binding:"omitempty"`
+ Name string `json:"name" binding:"required"`
+ BIO string `json:"bio" binding:"omitempty"`
}
type UpdateSecurityGroupRequest struct {
- Name string `json:"name" binding:"omitempty"`
- BIO string `json:"bio" binding:"omitempty"`
- Domain string `json:"domain" binding:"omitempty"`
- ProxyDomain string `json:"proxy_domain" binding:"omitempty"`
+ Name string `json:"name" binding:"omitempty"`
+ BIO string `json:"bio" binding:"omitempty"`
}
type GetSecurityGroupsQuery struct {
+ Name string `form:"name" binding:"omitempty"`
Page int `form:"page" binding:"omitempty,gte=1"`
PerPage int `form:"per_page" binding:"omitempty,gte=1,lte=50"`
- Name string `form:"name" binding:"omitempty"`
- Domain string `form:"domain" binding:"omitempty"`
}
diff --git a/manager/types/security_rule.go b/manager/types/security_rule.go
new file mode 100644
index 000000000..4351578f0
--- /dev/null
+++ b/manager/types/security_rule.go
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020 The Dragonfly Authors
+ *
+ * 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 types
+
+type SecurityRuleParams struct {
+ ID uint `uri:"id" binding:"required"`
+}
+
+type CreateSecurityRuleRequest struct {
+ Name string `json:"name" binding:"required"`
+ BIO string `json:"bio" binding:"omitempty"`
+ Domain string `json:"domain" binding:"required"`
+ ProxyDomain string `json:"proxy_domain" binding:"omitempty"`
+}
+
+type UpdateSecurityRuleRequest struct {
+ Name string `json:"name" binding:"omitempty"`
+ BIO string `json:"bio" binding:"omitempty"`
+ Domain string `json:"domain" binding:"omitempty"`
+ ProxyDomain string `json:"proxy_domain" binding:"omitempty"`
+}
+
+type GetSecurityRulesQuery struct {
+ Page int `form:"page" binding:"omitempty,gte=1"`
+ PerPage int `form:"per_page" binding:"omitempty,gte=1,lte=50"`
+ Name string `form:"name" binding:"omitempty"`
+ Domain string `form:"domain" binding:"omitempty"`
+ ProxyDomain string `form:"proxy_domain" binding:"omitempty"`
+}