blob: ef8e02b559f0f5366755d86d41f7c63eea326a04 [file] [log] [blame]
Dinesh Belwalkar6c0bc752020-04-24 23:47:53 +00001// Copyright 2018-present Open Networking Foundation
2// Copyright 2018-present Edgecore Networks Corporation
mce7028402019-07-18 04:10:01 +00003//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16package main
17
18import (
mce7028402019-07-18 04:10:01 +000019 "encoding/json"
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000020 logrus "github.com/sirupsen/logrus"
mce7028402019-07-18 04:10:01 +000021 "io/ioutil"
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000022 "net/http"
mce7028402019-07-18 04:10:01 +000023)
24
mc20a4b5f2019-10-16 20:28:24 +000025/* parse_map() parses the json structure, amap, and returns all sub-folder paths found at the 2nd level of the multiplayer structure
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000026 */
mc20a4b5f2019-10-16 20:28:24 +000027func parse_map(amap map[string]interface{}, level uint, archive map[string]bool) (paths []string) {
28 level = level + 1
29 for key, val := range amap {
30 switch val.(type) {
31 case map[string]interface{}:
32 p := parse_map(val.(map[string]interface{}), level, archive)
33 paths = append(paths, p...)
34 case []interface{}:
35 p := parse_array(val.([]interface{}), level, archive)
36 paths = append(paths, p...)
37 default:
38 if level == 2 && key == "@odata.id" {
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000039 /* sub-folder path of a resource can be found as the value of the key '@odata.id' showing up at the 2nd level of the data read from a resource. When a path is found, it's checked against the array 'archive' to avoid duplicates. */
mc20a4b5f2019-10-16 20:28:24 +000040 if _, ok := archive[val.(string)]; !ok {
41 archive[val.(string)] = true
42 paths = append(paths, val.(string))
43 }
44 }
45 }
46 }
47 return paths
48}
mce7028402019-07-18 04:10:01 +000049
mc20a4b5f2019-10-16 20:28:24 +000050/* parse_array() parses any vlaue, if in the form of an array, of a key-value pair found in the json structure, and returns any paths found.
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000051 */
mc20a4b5f2019-10-16 20:28:24 +000052func parse_array(anarray []interface{}, level uint, archive map[string]bool) (paths []string) {
53 for _, val := range anarray {
54 switch val.(type) {
55 case map[string]interface{}:
56 p := parse_map(val.(map[string]interface{}), level, archive)
57 paths = append(paths, p...)
58 }
59 }
60 return paths
61}
62
63/* read_resource() reads data from the specified Redfish resource, including its sub-folders, of the specified device ip and rerutnrs the data read.
64
65Based on careful examination of the data returned from several resources sampled, it was determined that sub-folder paths can be found as the value to the key '@odata.id' showing up at the 2nd level of the data read from a resource.
66*/
67func read_resource(ip string, resource string, archive map[string]bool) (data []string) {
68 resp, err := http.Get(ip + resource)
69 if resp != nil {
70 defer resp.Body.Close()
71 }
mce7028402019-07-18 04:10:01 +000072 if err != nil {
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000073 logrus.Errorf("Error http get %s", err)
mce7028402019-07-18 04:10:01 +000074 return
75 }
mc20a4b5f2019-10-16 20:28:24 +000076 body, err := ioutil.ReadAll(resp.Body)
77 if err != nil {
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000078 logrus.Errorf("Error Read %s", err)
mc20a4b5f2019-10-16 20:28:24 +000079 return
mce7028402019-07-18 04:10:01 +000080 }
mc20a4b5f2019-10-16 20:28:24 +000081
82 data = append(data, string(body))
83
84 m := map[string]interface{}{}
85 err = json.Unmarshal([]byte(body), &m)
86 if err != nil {
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000087 logrus.Errorf("Error Unmarshal %s", err)
mc20a4b5f2019-10-16 20:28:24 +000088 return
89 }
90
91 resources := parse_map(m, 0, archive)
92
93 for _, resource := range resources {
94 d := read_resource(ip, resource, archive)
95 data = append(data, d...)
96 }
97 return data
98}
99
100/* sample JSON files can be found in the samples folder */
101func (s *Server) get_status(ip string, resource string) (data []string) {
102 archive := make(map[string]bool)
103 base_ip := RF_DEFAULT_PROTOCOL + ip
104 /* 'archive' maintains a list of all resources that will be/have been visited to avoid duplicates */
105 archive[resource] = true
106 data = read_resource(base_ip, resource, archive)
107 return data
mce7028402019-07-18 04:10:01 +0000108}