diff options
author | Ritu Sood <ritu.sood@intel.com> | 2020-08-04 14:46:34 -0700 |
---|---|---|
committer | Ritu Sood <ritu.sood@intel.com> | 2020-08-20 11:42:12 -0700 |
commit | 6fc3a329aba55dfa2d4867bde9d8a3126b45f59a (patch) | |
tree | 21e39a03255198a8f0781a78ad9e2ade1f3c28ed /src/orchestrator/api | |
parent | 6e5ca4741dab0de3b4d89f410f0ff9d0313d6aee (diff) |
Add Validation for API's
Adding input validations for API based
on Json schemas
Issue-ID: MULTICLOUD-1096
Signed-off-by: Ritu Sood <ritu.sood@intel.com>
Change-Id: If6591bdef6305f87cbce7ef56d894376f687c6c1
Diffstat (limited to 'src/orchestrator/api')
24 files changed, 980 insertions, 32 deletions
diff --git a/src/orchestrator/api/add_intents_handler.go b/src/orchestrator/api/add_intents_handler.go index ac8b400d..21a33739 100644 --- a/src/orchestrator/api/add_intents_handler.go +++ b/src/orchestrator/api/add_intents_handler.go @@ -31,6 +31,7 @@ type intentHandler struct { client moduleLib.IntentManager } +// Add Intent in Deployment Group func (h intentHandler) addIntentHandler(w http.ResponseWriter, r *http.Request) { var i moduleLib.Intent @@ -45,8 +46,11 @@ func (h intentHandler) addIntentHandler(w http.ResponseWriter, r *http.Request) return } - if i.MetaData.Name == "" { - http.Error(w, "Missing Intent in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/deployment-intent.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, i) + if err != nil { + http.Error(w, err.Error(), httpError) return } diff --git a/src/orchestrator/api/app_intent_handler.go b/src/orchestrator/api/app_intent_handler.go index 56811d2d..a51b9b92 100644 --- a/src/orchestrator/api/app_intent_handler.go +++ b/src/orchestrator/api/app_intent_handler.go @@ -48,8 +48,11 @@ func (h appIntentHandler) createAppIntentHandler(w http.ResponseWriter, r *http. return } - if a.MetaData.Name == "" { - http.Error(w, "Missing AppIntentName in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/generic-placement-intent-app.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, a) + if err != nil { + http.Error(w, err.Error(), httpError) return } diff --git a/src/orchestrator/api/app_profilehandler.go b/src/orchestrator/api/app_profilehandler.go index f2475e23..2fa0f26d 100644 --- a/src/orchestrator/api/app_profilehandler.go +++ b/src/orchestrator/api/app_profilehandler.go @@ -73,6 +73,13 @@ func (h appProfileHandler) createAppProfileHandler(w http.ResponseWriter, r *htt return } + jsonFile := "json-schemas/metadata.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, ap) + if err != nil { + http.Error(w, err.Error(), httpError) + return + } //Read the file section and ignore the header file, _, err := r.FormFile("file") if err != nil { @@ -88,7 +95,11 @@ func (h appProfileHandler) createAppProfileHandler(w http.ResponseWriter, r *htt http.Error(w, "Unable to read file", http.StatusUnprocessableEntity) return } - + // Limit file Size to 1 GB + if len(content) > 1073741824 { + http.Error(w, "File Size Exceeds 1 GB", http.StatusUnprocessableEntity) + return + } err = validation.IsTarGz(bytes.NewBuffer(content)) if err != nil { http.Error(w, "Error in file format", http.StatusUnprocessableEntity) diff --git a/src/orchestrator/api/apphandler.go b/src/orchestrator/api/apphandler.go index 2c81431c..7d901a8f 100644 --- a/src/orchestrator/api/apphandler.go +++ b/src/orchestrator/api/apphandler.go @@ -70,9 +70,11 @@ func (h appHandler) createAppHandler(w http.ResponseWriter, r *http.Request) { return } - // Name is required. - if a.Metadata.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/metadata.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, a) + if err != nil { + http.Error(w, err.Error(), httpError) return } @@ -84,14 +86,17 @@ func (h appHandler) createAppHandler(w http.ResponseWriter, r *http.Request) { } defer file.Close() - //Convert the file content to base64 for storage content, err := ioutil.ReadAll(file) if err != nil { http.Error(w, "Unable to read file", http.StatusUnprocessableEntity) return } - + // Limit file Size to 1 GB + if len(content) > 1073741824 { + http.Error(w, "File Size Exceeds 1 GB", http.StatusUnprocessableEntity) + return + } err = validation.IsTarGz(bytes.NewBuffer(content)) if err != nil { http.Error(w, "Error in file format", http.StatusUnprocessableEntity) diff --git a/src/orchestrator/api/composite_app_handler.go b/src/orchestrator/api/composite_app_handler.go index ab052f00..1e69c353 100644 --- a/src/orchestrator/api/composite_app_handler.go +++ b/src/orchestrator/api/composite_app_handler.go @@ -21,9 +21,9 @@ import ( "io" "net/http" - moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module" - "github.com/gorilla/mux" + "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation" + moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module" ) // compositeAppHandler to store backend implementations objects @@ -47,10 +47,11 @@ func (h compositeAppHandler) createHandler(w http.ResponseWriter, r *http.Reques http.Error(w, err.Error(), http.StatusUnprocessableEntity) return } - - // Name is required. - if c.Metadata.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/composite-app.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, c) + if err != nil { + http.Error(w, err.Error(), httpError) return } diff --git a/src/orchestrator/api/composite_profilehandler.go b/src/orchestrator/api/composite_profilehandler.go index 66c64dda..5a3fb19c 100644 --- a/src/orchestrator/api/composite_profilehandler.go +++ b/src/orchestrator/api/composite_profilehandler.go @@ -21,6 +21,7 @@ import ( "io" "net/http" + "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation" moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module" "github.com/gorilla/mux" @@ -48,8 +49,11 @@ func (h compositeProfileHandler) createHandler(w http.ResponseWriter, r *http.Re return } - if cpf.Metadata.Name == "" { - http.Error(w, "Missing compositeProfileName in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/metadata.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, cpf) + if err != nil { + http.Error(w, err.Error(), httpError) return } diff --git a/src/orchestrator/api/controllerhandler.go b/src/orchestrator/api/controllerhandler.go index 5df691f3..be300d89 100644 --- a/src/orchestrator/api/controllerhandler.go +++ b/src/orchestrator/api/controllerhandler.go @@ -87,9 +87,11 @@ func (h controllerHandler) createHandler(w http.ResponseWriter, r *http.Request) return } - // Name is required. - if m.Metadata.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/controller.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, m) + if err != nil { + http.Error(w, err.Error(), httpError) return } diff --git a/src/orchestrator/api/deployment_intent_groups_handler.go b/src/orchestrator/api/deployment_intent_groups_handler.go index 7620737b..76dea14c 100644 --- a/src/orchestrator/api/deployment_intent_groups_handler.go +++ b/src/orchestrator/api/deployment_intent_groups_handler.go @@ -21,8 +21,8 @@ import ( "io" "net/http" - moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation" + moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module" "github.com/gorilla/mux" ) @@ -49,8 +49,11 @@ func (h deploymentIntentGroupHandler) createDeploymentIntentGroupHandler(w http. return } - if d.MetaData.Name == "" { - http.Error(w, "Missing deploymentIntentGroupName in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/deployment-group-intent.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, d) + if err != nil { + http.Error(w, err.Error(), httpError) return } diff --git a/src/orchestrator/api/generic_placement_intent_handler.go b/src/orchestrator/api/generic_placement_intent_handler.go index 02dbf0be..16f1f234 100644 --- a/src/orchestrator/api/generic_placement_intent_handler.go +++ b/src/orchestrator/api/generic_placement_intent_handler.go @@ -49,8 +49,11 @@ func (h genericPlacementIntentHandler) createGenericPlacementIntentHandler(w htt return } - if g.MetaData.Name == "" { - http.Error(w, "Missing genericPlacementIntentName in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/generic-placement-intent.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, g) + if err != nil { + http.Error(w, err.Error(), httpError) return } diff --git a/src/orchestrator/api/json-schemas/cluster-kv.json b/src/orchestrator/api/json-schemas/cluster-kv.json new file mode 100644 index 00000000..c7013bab --- /dev/null +++ b/src/orchestrator/api/json-schemas/cluster-kv.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "required": [ + "kv" + ], + "type": "object", + "properties": { + "kv": { + "items": { + "additionalProperties": { + "type": "string", + "maxLength": 128 + }, + "type": "object" + }, + "type": "array" + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/cluster-label.json b/src/orchestrator/api/json-schemas/cluster-label.json new file mode 100644 index 00000000..22267b3d --- /dev/null +++ b/src/orchestrator/api/json-schemas/cluster-label.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "label-name": { + "description": "Logical Cloud to use for this intent", + "type": "string", + "example": "cluster-label-1", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/composite-app.json b/src/orchestrator/api/json-schemas/composite-app.json new file mode 100644 index 00000000..3f976831 --- /dev/null +++ b/src/orchestrator/api/json-schemas/composite-app.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "version": { + "description": "Composite Application Version", + "type": "string", + "example": "v1", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/composite-profile.json b/src/orchestrator/api/json-schemas/composite-profile.json new file mode 100644 index 00000000..e404a64c --- /dev/null +++ b/src/orchestrator/api/json-schemas/composite-profile.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "app-name": { + "description": "Application Name", + "required": [ + "app-name" + ], + "type": "string", + "example": "Application1", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/controller.json b/src/orchestrator/api/json-schemas/controller.json new file mode 100644 index 00000000..3263ff21 --- /dev/null +++ b/src/orchestrator/api/json-schemas/controller.json @@ -0,0 +1,73 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "required": [ + "host", + "port", + "type", + "priority" + ], + "type": "object", + "properties": { + "priority": { + "description": "Priority of controller to be called", + "type": "integer", + "example": 4, + "minimum": 0, + "maximum": 100 + }, + "host": { + "description": "Controller reachibility information", + "type": "string", + "example": "10.7.100.4", + "maxLength": 128 + }, + "type": { + "description": "Type of controller (placement, action are 2 types supported)", + "type": "string", + "example": "placement", + "maxLength": 48 + }, + "port": { + "description": "Port for controller", + "type": "integer", + "minimum": 0, + "maximum": 50000, + "example": 9029 + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/deployment-group-intent.json b/src/orchestrator/api/json-schemas/deployment-group-intent.json new file mode 100644 index 00000000..2740747b --- /dev/null +++ b/src/orchestrator/api/json-schemas/deployment-group-intent.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "required": [ + "profile", + "version" + ], + "type": "object", + "description": "DepSpecData has profile, version, OverrideValuesObj", + "properties": { + "override-values": { + "items": { + "required": [ + "app-name", + "values" + ], + "type": "object", + "description": "OverrideValues has appName and ValuesObj", + "properties": { + "app-name": { + "type": "string" + }, + "values": { + "additionalProperties": { + "type": "string", + "maxLength": 128 + }, + "type": "object" + } + } + }, + "type": "array" + }, + "profile": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "version": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/deployment-intent.json b/src/orchestrator/api/json-schemas/deployment-intent.json new file mode 100644 index 00000000..6bdc0b43 --- /dev/null +++ b/src/orchestrator/api/json-schemas/deployment-intent.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "required": [ + "intent" + ], + "type": "object", + "description": "IntentSpecData has Intent", + "properties": { + "intent": { + "additionalProperties": { + "type": "string", + "maxLength": 128 + }, + "type": "object", + "example": { + "generic-placement-intent": "gpi-name" + } + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } +}
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/generic-placement-intent-app.json b/src/orchestrator/api/json-schemas/generic-placement-intent-app.json new file mode 100644 index 00000000..0b6447c2 --- /dev/null +++ b/src/orchestrator/api/json-schemas/generic-placement-intent-app.json @@ -0,0 +1,117 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "properties": { + "app-name": { + "type": "string", + "example": "appl", + "maxLength": 128 + }, + "anyOf": { + "items": { + "type": "object", + "description": "AnyOf consists of Array of ProviderName & ClusterLabelNames", + "properties": { + "cluster-label-name": { + "type": "string", + "example": "east", + "maxLength": 128 + }, + "provider-name": { + "type": "string", + "example": "provider1", + "maxLength": 128 + }, + "cluster-name": { + "type": "string", + "example": "cluster1", + "maxLength": 128 + } + } + }, + "type": "array" + }, + "allOf": { + "items": { + "type": "object", + "description": "AllOf ProviderName, ClusterName, ClusterLabelName and AnyOfArray", + "properties": { + "provider-name": { + "type": "string", + "example": "provider2", + "maxLength": 128 + }, + "cluster-label-name": { + "type": "string", + "example": "west", + "maxLength": 128 + }, + "anyOf": { + "items": { + "type": "object", + "description": "AnyOf consists of Array of ProviderName & ClusterLabelNames", + "properties": { + "cluster-label-name": { + "type": "string", + "example": "east", + "maxLength": 128 + }, + "provider-name": { + "type": "string", + "example": "provider1", + "maxLength": 128 + }, + "cluster-name": { + "type": "string", + "example": "cluster1", + "maxLength": 128 + } + } + }, + "type": "array" + }, + "cluster-name": { + "type": "string", + "example": "cluster2", + "maxLength": 128 + } + } + }, + "type": "array" + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } +}
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/generic-placement-intent.json b/src/orchestrator/api/json-schemas/generic-placement-intent.json new file mode 100644 index 00000000..44df9087 --- /dev/null +++ b/src/orchestrator/api/json-schemas/generic-placement-intent.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Spec", + "properties": { + "logical-cloud": { + "description": "Logical Cloud to use for this intent", + "required": [ + "logical-cloud" + ], + "type": "string", + "example": "cloud1", + "maxLength": 128 + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/metadata.json b/src/orchestrator/api/json-schemas/metadata.json new file mode 100644 index 00000000..960545ee --- /dev/null +++ b/src/orchestrator/api/json-schemas/metadata.json @@ -0,0 +1,37 @@ + +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/network-load-interface.json b/src/orchestrator/api/json-schemas/network-load-interface.json new file mode 100644 index 00000000..dd5b40d1 --- /dev/null +++ b/src/orchestrator/api/json-schemas/network-load-interface.json @@ -0,0 +1,77 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "required": [ + "interface", + "name" + ], + "type": "object", + "properties": { + "interface": { + "description": "interface Name", + "type": "string", + "example": "eth0", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "macAddress": { + "description": "Name of the network", + "type": "string", + "example": "x.x.x.x", + "maxLength": 128 + }, + "ipAddress": { + "description": "Name of the network", + "type": "string", + "example": "0.0.0.0", + "maxLength": 128 + }, + "name": { + "description": "Name of the network", + "type": "string", + "example": "provider-1", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "defaultGateway": { + "description": "Is this interface default gateway", + "type": "boolean", + "example": false, + "maxLength": 128 + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + }
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/network-workload.json b/src/orchestrator/api/json-schemas/network-workload.json new file mode 100644 index 00000000..c5dc14cb --- /dev/null +++ b/src/orchestrator/api/json-schemas/network-workload.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "type": "object", + "description": "Newtwork Workload Intent", + "properties": { + "spec": { + "type": "object", + "properties": { + "workload-resource": { + "description": "Name of the workload", + "type": "string", + "example": "firewall", + "maxLength": 254, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "type": { + "description": "Type of the workload", + "type": "string", + "example": "deployment", + "maxLength": 128 + }, + "application-name": { + "description": "Application Name", + "type": "string", + "example": "Application1", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } + } + } +}
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/provider-network.json b/src/orchestrator/api/json-schemas/provider-network.json new file mode 100644 index 00000000..0aef0304 --- /dev/null +++ b/src/orchestrator/api/json-schemas/provider-network.json @@ -0,0 +1,122 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "required": [ + "cniType", + "ipv4Subnets", + "providerNetType", + "vlan" + ], + "type": "object", + "properties": { + "ipv4Subnets": { + "items": { + "required": [ + "name", + "subnet" + ], + "type": "object", + "properties": { + "subnet": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "excludeIps": { + "type": "string", + "maxLength": 128 + }, + "gateway": { + "type": "string", + "maxLength": 128 + }, + "name": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + } + }, + "type": "array" + }, + "cniType": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "vlan": { + "required": [ + "logicalInterfaceName", + "nodeLabelList", + "providerInterfaceName", + "vlanID", + "vlanNodeSelector" + ], + "type": "object", + "properties": { + "vlanNodeSelector": { + "type": "string", + "maxLength": 128 + }, + "nodeLabelList": { + "items": { + "type": "string", + "maxLength": 128 + }, + "type": "array" + }, + "providerInterfaceName": { + "type": "string", + "maxLength": 128 + }, + "vlanID": { + "type": "string", + "maxLength": 128 + }, + "logicalInterfaceName": { + "type": "string", + "maxLength": 128 + } + } + }, + "providerNetType": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } +}
\ No newline at end of file diff --git a/src/orchestrator/api/json-schemas/virtual-network.json b/src/orchestrator/api/json-schemas/virtual-network.json new file mode 100644 index 00000000..f2bc9d3d --- /dev/null +++ b/src/orchestrator/api/json-schemas/virtual-network.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "spec": { + "properties": { + "ipv4Subnets": { + "items": { + "required": [ + "name", + "subnet" + ], + "type": "object", + "properties": { + "subnet": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "excludeIps": { + "type": "string", + "maxLength": 1024 + }, + "gateway": { + "type": "string", + "maxLength": 128 + }, + "name": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + } + }, + "type": "array" + }, + "cniType": { + "type": "string", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + } + } + }, + "metadata": { + "required": ["name"], + "properties": { + "userData2": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some more data", + "maxLength": 512 + }, + "userData1": { + "description": "User relevant data for the resource", + "type": "string", + "example": "Some data", + "maxLength": 512 + }, + "name": { + "description": "Name of the resource", + "type": "string", + "example": "ResName", + "maxLength": 128, + "pattern": "[-_0-9a-zA-Z]+$" + }, + "description": { + "description": "Description for the resource", + "type": "string", + "example": "Resource description", + "maxLength": 1024 + } + } + } + } +}
\ No newline at end of file diff --git a/src/orchestrator/api/projecthandler.go b/src/orchestrator/api/projecthandler.go index 83211b64..6b512804 100644 --- a/src/orchestrator/api/projecthandler.go +++ b/src/orchestrator/api/projecthandler.go @@ -21,9 +21,9 @@ import ( "io" "net/http" - moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module" - "github.com/gorilla/mux" + "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation" + moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module" ) // Used to store backend implementations objects @@ -47,10 +47,11 @@ func (h projectHandler) createHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusUnprocessableEntity) return } - - // Name is required. - if p.MetaData.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) + jsonFile := "json-schemas/metadata.json" + // Verify JSON Body + err, httpError := validation.ValidateJsonSchemaData(jsonFile, p) + if err != nil { + http.Error(w, err.Error(), httpError) return } |