Repository: kubeflow/pipelines

Issue:
[sdk] `kfp run submit` fails when paramerer values contain '=' with "dictionary update sequence element"
### Environment

*  KFP version: 
<!-- For more information, see an overview of KFP installation options: https://www.kubeflow.org/docs/pipelines/installation/overview/. -->
*  KFP SDK version: 1.4.0, 1.5.0
<!-- Specify the version of Kubeflow Pipelines that you are using. The version number appears in the left side navigation of user interface.
To find the version number, See version number shows on bottom of KFP UI left sidenav. -->
*  All dependencies version: n/a
<!-- Specify the output of the following shell command: $pip list | grep kfp -->

### Steps to reproduce

* Compile test pipeline below (run py script)

```py
import kfp as kfp

@kfp.components.func_to_container_op
def print_func(param: str):
    print(str(param))
    return

@kfp.dsl.pipeline(name='pipeline')
def pipeline(param: str):
    print_func(param)
    return

if __name__ == '__main__':
    kfp.compiler.Compiler().compile(pipeline, __file__ + ".zip")
```

* Upload to KF
* Grab the `pipeline-id` to use it in the command line sdk
* Using the command line SDK, run the following:

```sh
$ kfp run submit --pipeline-id <pipeline-id> --experiment-name 'Test = parsing' param=12345   # Succeeds
$ kfp run submit --pipeline-id <pipeline-id> --experiment-name 'Test = parsing' param=some_name=4567    # Fails
dictionary update sequence element #0 has length 3; 2 is required
```

Running the parameter directly from the KFP UI with value `some_name=4567` works fine and prints `some_name=4567`.


#### Problem Explanation
The pipeline expects an input parameter named `param` to run and it prints the value of that param. The SDK will parse pipeline parameters on the `=` sign [here](https://github.com/kubeflow/pipelines/blob/master/sdk/python/kfp/cli/run.py#L79). The value contains an `=` sign, so we are trying to update the `dict()` with `('param', 'some_name', '4567')` when the goal is to update it with `('param', 'some_name=4567')`.

#### Problem Significance
The equality sign `=` is typically used to partition datasets in distributed storage (S3, HDFS, etc) leading to paths like
```
hdfs://path/to/table/year_partition=2020/month_partition=01/other_partition=other_value/file1.parquet
hdfs://path/to/table/year_partition=2020/month_partition=02/other_partition=other_value/file1.parquet
...
```
Due to the problem discussed above, we cannot use the CLI SDK to provide parameters that contain the `=` sign. However, we _can_ use the KFP UI and pass such paramters, leading to inconsistent behavior.

<!--
Specify how to reproduce the problem. 
This may include information such as: a description of the process, code snippets, log output, or screenshots.
-->

### Expected result

<!-- What should the correct behavior be? -->

Running
```sh
$ kfp run submit --pipeline-id <pipeline-id> --experiment-name 'Test = parsing' param=some_name=4567 
```
should succeed just like running the pipeline via the KFP UI with the value `some_name=4567` for the run parameter **param**.



### Materials and Reference

<!-- Help us debug this issue by providing resources such as: sample code, background context, or links to references. -->

#### Suggested Solution
[This line](https://github.com/kubeflow/pipelines/blob/master/sdk/python/kfp/cli/run.py#L79) should be
```py
    arg_dict = dict(arg.split('=', maxsplit=1) for arg in args)
```

---

<!-- Don't delete message below to encourage users to support your issue! -->
Impacted by this bug? Give it a 👍. We prioritise the issues with the most 👍.



Discussion:
/assign

Will take a look. 

Resolving patch:
diff --git a/sdk/python/kfp/cli/run.py b/sdk/python/kfp/cli/run.py
--- a/sdk/python/kfp/cli/run.py
+++ b/sdk/python/kfp/cli/run.py
@@ -76,7 +76,8 @@ def submit(ctx, experiment_name, run_name, package_file, pipeline_id, pipeline_n
         click.echo('You must provide one of [package_file, pipeline_id, version].', err=True)
         sys.exit(1)
 
-    arg_dict = dict(arg.split('=') for arg in args)
+    arg_dict = dict(arg.split('=', maxsplit=1) for arg in args)
+
     experiment = client.create_experiment(experiment_name)
     run = client.run_pipeline(experiment.id, run_name, package_file, arg_dict, pipeline_id,
                               version_id=version)


Test patch: