summaryrefslogtreecommitdiffstats
path: root/components/model-catalog/blueprint-model/test-blueprint
diff options
context:
space:
mode:
Diffstat (limited to 'components/model-catalog/blueprint-model/test-blueprint')
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/artifact_types.json44
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/data_types.json50
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json200
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/policy_types.json2
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/relationship_types.json2
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json108
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/resources_definition_types.json17
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Environments/requirements.txt3
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Plans/CONFIG_ExecAnsiblePlaybook.xml27
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/first.yaml28
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/inventory.yaml13
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-mapping.json35
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-template.vtl1
13 files changed, 421 insertions, 109 deletions
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/artifact_types.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/artifact_types.json
index a6a34ae8e..6e5cfc3a1 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/artifact_types.json
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/artifact_types.json
@@ -1,20 +1,34 @@
{
- "artifact_types": {
- "artifact-script-python": {
- "description": "Python Script file",
- "version": "1.0.0",
- "derived_from": "tosca.artifacts.Implementation",
- "file_ext": [
- "py"
- ]
+ "artifact_types" : {
+ "artifact-directed-graph" : {
+ "description" : "Directed Graph File",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "json", "xml" ]
},
- "artifact-script-ansible": {
- "description": "Ansible Script file",
- "version": "1.0.0",
- "file_ext": [
- "yaml"
- ],
- "derived_from": "tosca.artifacts.Implementation"
+ "artifact-mapping-resource" : {
+ "description" : "Resource Mapping File used along with Configuration template",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "json" ]
+ },
+ "artifact-script-ansible" : {
+ "description" : "Ansible Script file",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "yaml" ]
+ },
+ "artifact-script-python" : {
+ "description" : "Python Script file",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "py" ]
+ },
+ "artifact-template-velocity" : {
+ "description" : " Velocity Template used for Configuration",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.artifacts.Implementation",
+ "file_ext" : [ "vtl" ]
}
}
} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/data_types.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/data_types.json
index 25efb3656..b9c092ef3 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/data_types.json
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/data_types.json
@@ -1,29 +1,41 @@
{
- "data_types": {
- "dt-system-packages": {
- "description": "This represent System Package Data Type",
- "version": "1.0.0",
- "properties": {
- "type": {
- "required": true,
- "type": "string",
- "constraints": [
- {
- "valid_values": [
- "ansible_galaxy", "pip"
- ]
- }
- ]
+ "data_types" : {
+ "dt-execute-remote-ansible-properties" : {
+ "description" : "Dynamic DataType definition for workflow(execute-remote-ansible).",
+ "version" : "1.0.0",
+ "properties" : {
+ "password" : {
+ "type" : "string"
},
- "package": {
- "required": true,
- "type": "list",
+ "ip" : {
+ "type" : "string"
+ },
+ "username" : {
+ "type" : "string"
+ }
+ },
+ "derived_from" : "tosca.datatypes.Dynamic"
+ },
+ "dt-system-packages" : {
+ "description" : "This represent System Package Data Type",
+ "version" : "1.0.0",
+ "properties" : {
+ "type" : {
+ "required" : true,
+ "type" : "string",
+ "constraints" : [ {
+ "valid_values" : [ "ansible_galaxy", "pip" ]
+ } ]
+ },
+ "package" : {
+ "required" : true,
+ "type" : "list",
"entry_schema" : {
"type" : "string"
}
}
},
- "derived_from": "tosca.datatypes.Root"
+ "derived_from" : "tosca.datatypes.Root"
}
}
} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json
index a66e3bc9d..ddbccac93 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/node_types.json
@@ -1,52 +1,52 @@
{
- "node_types": {
- "component-remote-python-executor": {
- "description": "This is Remote Python Execution Component.",
- "version": "1.0.0",
- "attributes": {
- "prepare-environment-logs": {
- "required": false,
- "type": "string"
+ "node_types" : {
+ "component-remote-python-executor" : {
+ "description" : "This is Remote Python Execution Component.",
+ "version" : "1.0.0",
+ "attributes" : {
+ "prepare-environment-logs" : {
+ "required" : false,
+ "type" : "string"
},
- "execute-command-logs": {
- "required": false,
- "type": "string"
+ "execute-command-logs" : {
+ "required" : false,
+ "type" : "string"
}
},
- "capabilities": {
- "component-node": {
- "type": "tosca.capabilities.Node"
+ "capabilities" : {
+ "component-node" : {
+ "type" : "tosca.capabilities.Node"
}
},
- "interfaces": {
- "ComponentRemotePythonExecutor": {
- "operations": {
- "process": {
- "inputs": {
- "endpoint-selector": {
- "description": "Remote Container or Server selector name.",
- "required": false,
- "type": "string",
- "default": "remote-python"
+ "interfaces" : {
+ "ComponentRemotePythonExecutor" : {
+ "operations" : {
+ "process" : {
+ "inputs" : {
+ "endpoint-selector" : {
+ "description" : "Remote Container or Server selector name.",
+ "required" : false,
+ "type" : "string",
+ "default" : "remote-python"
},
- "dynamic-properties": {
- "description": "Dynamic Json Content or DSL Json reference.",
- "required": false,
- "type": "json"
+ "dynamic-properties" : {
+ "description" : "Dynamic Json Content or DSL Json reference.",
+ "required" : false,
+ "type" : "json"
},
- "argument-properties": {
- "description": "Argument Json Content or DSL Json reference.",
- "required": false,
- "type": "json"
+ "argument-properties" : {
+ "description" : "Argument Json Content or DSL Json reference.",
+ "required" : false,
+ "type" : "json"
},
- "command": {
- "description": "Command to execute.",
- "required": true,
+ "command" : {
+ "description" : "Command to execute.",
+ "required" : true,
"type" : "string"
},
- "packages": {
- "description": "Packages to install based on type.",
- "required": false,
+ "packages" : {
+ "description" : "Packages to install based on type.",
+ "required" : false,
"type" : "list",
"entry_schema" : {
"type" : "dt-system-packages"
@@ -57,12 +57,126 @@
}
}
},
- "derived_from": "tosca.nodes.Component"
+ "derived_from" : "tosca.nodes.Component"
},
- "tosca.nodes.Component": {
- "description": "This is default Component Node",
- "version": "1.0.0",
- "derived_from": "tosca.nodes.Root"
+ "component-resource-resolution" : {
+ "description" : "This is Resource Assignment Component API",
+ "version" : "1.0.0",
+ "attributes" : {
+ "assignment-params" : {
+ "required" : true,
+ "type" : "string"
+ }
+ },
+ "capabilities" : {
+ "component-node" : {
+ "type" : "tosca.capabilities.Node"
+ }
+ },
+ "interfaces" : {
+ "ResourceResolutionComponent" : {
+ "operations" : {
+ "process" : {
+ "inputs" : {
+ "resolution-key" : {
+ "description" : "Key for service instance related correlation.",
+ "required" : false,
+ "type" : "string"
+ },
+ "store-result" : {
+ "description" : "Whether or not to store the output.",
+ "required" : false,
+ "type" : "boolean"
+ },
+ "resource-type" : {
+ "description" : "Request type.",
+ "required" : false,
+ "type" : "string"
+ },
+ "artifact-prefix-names" : {
+ "description" : "Template , Resource Assignment Artifact Prefix names",
+ "required" : true,
+ "type" : "list",
+ "entry_schema" : {
+ "type" : "string"
+ }
+ },
+ "request-id" : {
+ "description" : "Request Id, Unique Id for the request.",
+ "required" : true,
+ "type" : "string"
+ },
+ "resource-id" : {
+ "description" : "Resource Id.",
+ "required" : false,
+ "type" : "string"
+ },
+ "action-name" : {
+ "description" : "Action Name of the process",
+ "required" : false,
+ "type" : "string"
+ },
+ "dynamic-properties" : {
+ "description" : "Dynamic Json Content or DSL Json reference.",
+ "required" : false,
+ "type" : "json"
+ }
+ },
+ "outputs" : {
+ "resource-assignment-params" : {
+ "required" : true,
+ "type" : "string"
+ },
+ "status" : {
+ "required" : true,
+ "type" : "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "derived_from" : "tosca.nodes.Component"
+ },
+ "dg-generic" : {
+ "description" : "This is Generic Directed Graph Type",
+ "version" : "1.0.0",
+ "properties" : {
+ "content" : {
+ "required" : true,
+ "type" : "string"
+ },
+ "dependency-node-templates" : {
+ "description" : "Dependent Step Components NodeTemplate name.",
+ "required" : true,
+ "type" : "list",
+ "entry_schema" : {
+ "type" : "string"
+ }
+ }
+ },
+ "derived_from" : "tosca.nodes.Workflow"
+ },
+ "source-input" : {
+ "description" : "This is Input Resource Source Node Type",
+ "version" : "1.0.0",
+ "properties" : { },
+ "derived_from" : "tosca.nodes.ResourceSource"
+ },
+ "tosca.nodes.Component" : {
+ "description" : "This is default Component Node",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.nodes.Root"
+ },
+ "tosca.nodes.ResourceSource" : {
+ "description" : "TOSCA base type for Resource Sources",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.nodes.Root"
+ },
+ "tosca.nodes.Workflow" : {
+ "description" : "This is Directed Graph Node Type",
+ "version" : "1.0.0",
+ "derived_from" : "tosca.nodes.Root"
}
}
} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/policy_types.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/policy_types.json
index 2442ce877..1e44cc70a 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/policy_types.json
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/policy_types.json
@@ -1,3 +1,3 @@
{
- "policy_types": {}
+ "policy_types" : { }
} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/relationship_types.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/relationship_types.json
index 097a30afd..4ddd7a57c 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/relationship_types.json
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/relationship_types.json
@@ -1,3 +1,3 @@
{
- "relationship_types": {}
+ "relationship_types" : { }
} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json
index 4c3ece381..656176c11 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/remote_scripts.json
@@ -26,15 +26,23 @@
}
],
"dsl_definitions": {
- "execute-argument-properties": {
- "input": "data"
- },
"remote-argument-properties": {
- "arg-0": "-a",
- "arg-1": "sample-data 1",
- "arg-4": "sample-data 4",
- "arg-3": "sample-data 3",
- "arg-2": "-b"
+ "input": {
+ "get_input": "input"
+ }
+ },
+ "ansible-argument-properties": {
+ "arg0": "-i",
+ "arg1": "Scripts/ansible/inventory.yaml",
+ "arg2": "--extra-vars",
+ "arg3": {
+ "get_attribute": [
+ "resolve-ansible-vars",
+ "",
+ "assignment-params",
+ "ansible-vars"
+ ]
+ }
}
},
"topology_template": {
@@ -82,7 +90,7 @@
"steps": {
"execute-script": {
"description": "Execute Remote Ansible Script",
- "target": "execute-remote-ansible",
+ "target": "execute-remote-ansible-process",
"activities": [
{
"call_operation": ""
@@ -90,8 +98,35 @@
]
}
},
- "inputs": {},
+ "inputs": {
+ "ip": {
+ "required": false,
+ "type": "string"
+ },
+ "username": {
+ "required": false,
+ "type": "string"
+ },
+ "password": {
+ "required": false,
+ "type": "string"
+ },
+ "execute-remote-ansible-properties": {
+ "description": "Dynamic PropertyDefinition for workflow(execute-remote-ansible).",
+ "required": true,
+ "type": "dt-execute-remote-ansible-properties"
+ }
+ },
"outputs": {
+ "ansible-variable-resolution": {
+ "type": "json",
+ "value": {
+ "get_attribute": [
+ "resolve-ansible-vars",
+ "assignment-params"
+ ]
+ }
+ },
"prepare-environment-logs": {
"type": "string",
"value": {
@@ -133,8 +168,7 @@
]
}
],
- "argument-properties": "*remote-argument-properties",
- "dynamic-properties": "*execute-argument-properties"
+ "argument-properties": "*remote-argument-properties"
}
}
}
@@ -147,6 +181,53 @@
}
}
},
+ "execute-remote-ansible-process": {
+ "type": "dg-generic",
+ "properties": {
+ "content": {
+ "get_artifact": [
+ "SELF",
+ "dg-execute-remote-ansible-process"
+ ]
+ },
+ "dependency-node-templates": [
+ "resolve-ansible-vars",
+ "execute-remote-ansible"
+ ]
+ },
+ "artifacts": {
+ "dg-execute-remote-ansible-process": {
+ "type": "artifact-directed-graph",
+ "file": "Plans/CONFIG_ExecAnsiblePlaybook.xml"
+ }
+ }
+ },
+ "resolve-ansible-vars": {
+ "type": "component-resource-resolution",
+ "interfaces": {
+ "ResourceResolutionComponent": {
+ "operations": {
+ "process": {
+ "inputs": {
+ "artifact-prefix-names": [
+ "ansible-vars"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "artifacts": {
+ "ansible-vars-template": {
+ "type": "artifact-template-velocity",
+ "file": "Templates/ansible-vars-template.vtl"
+ },
+ "ansible-vars-mapping": {
+ "type": "artifact-mapping-resource",
+ "file": "Templates/ansible-vars-mapping.json"
+ }
+ }
+ },
"execute-remote-ansible": {
"type": "component-remote-python-executor",
"interfaces": {
@@ -157,7 +238,8 @@
"primary": "component-script"
},
"inputs": {
- "command": "ansible-playbook first.yaml",
+ "command": "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook first.yaml",
+ "argument-properties": "*ansible-argument-properties",
"packages": [
{
"type": "pip",
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/resources_definition_types.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/resources_definition_types.json
index 9e26dfeeb..b77f451ad 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/resources_definition_types.json
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Definitions/resources_definition_types.json
@@ -1 +1,16 @@
-{} \ No newline at end of file
+{
+ "hostname" : {
+ "tags" : "hostname",
+ "name" : "hostname",
+ "property" : {
+ "description" : "hostname",
+ "type" : "string"
+ },
+ "updated-by" : "Singal, Kapil <ks220y@att.com>",
+ "sources" : {
+ "input" : {
+ "type" : "source-input"
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Environments/requirements.txt b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Environments/requirements.txt
index cabb1f519..86247a035 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Environments/requirements.txt
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Environments/requirements.txt
@@ -1 +1,2 @@
-ansible \ No newline at end of file
+ansible
+ncclient \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Plans/CONFIG_ExecAnsiblePlaybook.xml b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Plans/CONFIG_ExecAnsiblePlaybook.xml
new file mode 100644
index 000000000..aad0a0d69
--- /dev/null
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Plans/CONFIG_ExecAnsiblePlaybook.xml
@@ -0,0 +1,27 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='CONFIG' version='1.0.0'>
+ <method rpc='ResolveAnsibleVar' mode='sync'>
+ <block atomic="true">
+ <execute plugin="resolve-ansible-vars" method="process">
+ <outcome value='failure'>
+ <return status="failure">
+ </return>
+ </outcome>
+ <outcome value='success'>
+ <execute plugin="execute-remote-ansible" method="process">
+ <outcome value='failure'>
+ <return status="failure">
+ </return>
+ </outcome>
+ <outcome value='success'>
+ <return status='success'>
+ </return>
+ </outcome>
+ </execute>
+ </outcome>
+ </execute>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/first.yaml b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/first.yaml
index 78d292e10..279733e48 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/first.yaml
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/first.yaml
@@ -1,22 +1,20 @@
---
-- name: Get Device Facts
- hosts: dc1
- roles:
- - juniper.junos
- connection: local
+- name: Get Device Running Config
+ hosts: all
gather_facts: no
+ connection: local
+ any_errors_fatal: True
+ serial: 5
tasks:
- - name: Checking NETCONF connectivity
- wait_for:
- host: "{{ inventory_hostname }}"
- port: 830
- timeout: 5
+ - name: Get Running Config
+ netconf_rpc:
+ rpc: get-config
+ content: |
+ <source><running/></source>
+ register: netconf_output
- - name: Retrieving information from devices running Junos OS
- juniper_junos_facts:
- host: "{{ inventory_hostname }}"
- - name: Print version
+ - name: Print Running Config
debug:
- var: junos.version \ No newline at end of file
+ var: netconf_output \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/inventory.yaml b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/inventory.yaml
new file mode 100644
index 000000000..fd3aa5057
--- /dev/null
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Scripts/ansible/inventory.yaml
@@ -0,0 +1,13 @@
+all:
+ children:
+ lab:
+ hosts:
+ nfx1:
+ ansible_ssh_host: "{{ ip }}"
+ ansible_network_os: junos
+
+ vars:
+ ansible_ssh_user: "{{ username }}"
+ ansible_ssh_pass: "{{ password }}"
+ ansible_connection: netconf
+ host_key_checking: False \ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-mapping.json b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-mapping.json
new file mode 100644
index 000000000..53f2122b3
--- /dev/null
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-mapping.json
@@ -0,0 +1,35 @@
+[
+ {
+ "name": "ip",
+ "input-param": true,
+ "property": {
+ "type": "string"
+ },
+ "dictionary-name": "hostname",
+ "dictionary-source": "input",
+ "dependencies": [
+ ]
+ },
+ {
+ "name": "username",
+ "input-param": true,
+ "property": {
+ "type": "string"
+ },
+ "dictionary-name": "hostname",
+ "dictionary-source": "input",
+ "dependencies": [
+ ]
+ },
+ {
+ "name": "password",
+ "input-param": true,
+ "property": {
+ "type": "string"
+ },
+ "dictionary-name": "hostname",
+ "dictionary-source": "input",
+ "dependencies": [
+ ]
+ }
+]
diff --git a/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-template.vtl b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-template.vtl
new file mode 100644
index 000000000..4c8c72224
--- /dev/null
+++ b/components/model-catalog/blueprint-model/test-blueprint/remote_scripts/Templates/ansible-vars-template.vtl
@@ -0,0 +1 @@
+'{"ip": "$ip","password": "$password","username": "$username"}' \ No newline at end of file