duanbing6955 2014-05-04 13:25
浏览 63

Opscode Chef REST API无效JSON

I am trying to integrate with Chef via PHP

I used the library https://github.com/dv1r/php-chef to communicate with the Hosted Enterprise Chef. When I retrieve information from Chef, everything is fine. I can also delete clients and such.

The problem starts when I try to send data to the server. I always get the error "Invalid JSON". The JSON that I am sending is valid according to http://jsonlint.com/ .

Does anybody know if i need to add and encoding type to the json_encode() inorder to fix this?

Code example:

    try{
        // Gets current data in Data-Bad `evns` Item `dev` (works)
        $res = $this->chef->get('/data/envs/dev');
    } catch (Exception $e){
        echo("Exception: ".$e->getMessage());
    }
    // Alter Data
    $res->testtt = "testess";
    try{
        // Set's new data to Data-bag `envs` Item `dev` (FAILS)
        $ret = $this->chef->put("/data/envs/dev",$res);
    } catch (Exception $e){
        die("Exception: <br>".$e->getMessage());
    }

The interesting part of the library:

    // json encode data
    if ($data && !is_string($data)) {
        $data = json_encode($data,JSON_UNESCAPED_UNICODE);
        $this->debug("data encoded to json: {$data}");
    }

    // sign the request
    $this->sign($endpoint, $method, $data, $header);
    $this->debug("request URL: {$url}");
    // initiate curl
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);

    // most people are using self-signed certs for chef, so its easiest to just
    // disable ssl verification
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

    // add data to post and put requests
    if ($method == 'POST' || $method == 'PUT')
    {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    // execute
    $raw_response = curl_exec($ch);

If I missed some critical information, please comment and I will add.

Thank you.

EDIT: More debug info -

Raw Responses:

First call to the API (GET) raw_response: {"name":"name","id":"dev"}

Second call (PUT) raw_response: {"error":["invalid JSON"]}

Output of curl_getinfo($ch) [PUT]:

    Array
    (
        [url] => https://api.opscode.com/organizations/MY_ORG/data/envs/dev
        [content_type] => text/html
        [http_code] => 400
        [header_size] => 426
        [request_size] => 1665
        [filetime] => -1
        [ssl_verify_result] => 0
        [redirect_count] => 1
        [total_time] => 0.175739
        [namelookup_time] => 2.0E-5
        [connect_time] => 0.02709
        [pretransfer_time] => 0.093261
        [size_upload] => 0
        [size_download] => 26
        [speed_download] => 147
        [speed_upload] => 0
        [download_content_length] => 26
        [upload_content_length] => 0
        [starttransfer_time] => 0.126115
        [redirect_time] => 0.049605
        [certinfo] => Array()
        [primary_ip] => 184.106.28.81
        [primary_port] => 443
        [local_ip] => xxx.xxx.xxx.50
        [local_port] => 33329
        [redirect_url] => 
        [request_header] => PUT /organizations/MY_ORG/data/envs/dev HTTP/1.1
    Host: api.opscode.com
    Accept: application/json
    Content-Type: application/json
    X-Chef-Version: 11.8.2
    X-Ops-Sign: algorithm=sha1;version=1.0
    X-Ops-UserId: USER
    X-Ops-Timestamp: 2014-05-07T13:39:55Z
    X-Ops-Content-Hash: qk8fSIReFrOMJ+Wk2y8yoe3EAgk=
    X-Ops-Authorization-1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    X-Ops-Authorization-6: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    )
  • 写回答

1条回答 默认 最新

  • dongzaheng4449 2014-05-12 08:15
    关注

    The $res->testtt will be your main problem.

    The 'magic' conversion is somehow buggy. Cast to array and you'll be safest on what is done

    i.e:

    try{
        // Gets current data in Data-Bad `evns` Item `dev` (works)
        $res = (array) $this->chef->get('/data/envs/dev');
    } catch (Exception $e){
        echo("Exception: ".$e->getMessage());
    }
    // Alter Data
    $res['testtt'] = "testess";
    try{
        // Set's new data to Data-bag `envs` Item `dev` (FAILS)
        $ret = $this->chef->put("/data/envs/dev",$res);
    } catch (Exception $e){
        die("Exception: <br>".$e->getMessage());
    }
    

    Hope it will help.

    Edit for a working exemple

    <?php
     $envs = unserialize($_POST['envs']);
     foreach($_POST["datas"] as $env => $items) {
      ksort($items,SORT_NATURAL);
      $old = (array) $chef->get("/data/livraisons/".$env);
      $new = array_merge($old,$items);
      ksort($new,SORT_NATURAL);
      $chef->put("/data/livraisons/".$env,$new);
     }
    ?>
    

    I hope it will help you figure it out ..

    Warns:

    1. I'm on an open source chef server (11.0.10), maybe that's the point (even if I doubt about it)
    2. I'm using a slightly different version of the library which don't use constant with json_encode... see here: https://github.com/jenssegers/php-chef
    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序