Skip to content

Commit

Permalink
Merge pull request #191 from project-arlo/brcm_poc
Browse files Browse the repository at this point in the history
Brcm poc
  • Loading branch information
a-barboza authored Oct 21, 2019
2 parents 1e0c0b8 + 0074524 commit e4744ef
Show file tree
Hide file tree
Showing 26 changed files with 1,643 additions and 390 deletions.
1 change: 1 addition & 0 deletions config/transformer/models_list
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

openconfig-acl.yang
openconfig-acl-annot.yang
sonic-vxlan.yang
6 changes: 6 additions & 0 deletions models/yang/openconfig-spanning-tree-ext.yang
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ module openconfig-spanning-tree-ext {
description
"Instance identifier of STP";
}

leaf root-port-name {
type string;
description
"Name of root port";
}
}

grouping vlan-interface-extra-state-field {
Expand Down
105 changes: 105 additions & 0 deletions models/yang/sonic/sonic-vxlan.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
module sonic-vxlan {
namespace "http://github.com/Azure/sonic-vxlan";
prefix svxlan;
yang-version 1.1;

import ietf-yang-types {
prefix yang;
}

import ietf-inet-types {
prefix inet;
}

organization
"SONiC";

contact
"SONiC";

description
"SONIC VXLAN";

revision 2019-10-01 {
description
"Initial revision.";
}

container sonic-vxlan {

container VXLAN_TUNNEL {

list VXLAN_TUNNEL_LIST {
key "name";
max-elements 1;

leaf name {
type string;
}

leaf src_ip {
mandatory true;
type inet:ipv4-address;
}
}
}

container VXLAN_TUNNEL_MAP {

list VXLAN_TUNNEL_MAP_LIST {
key "name mapname";

leaf name {
type leafref {
path "../../../VXLAN_TUNNEL/VXLAN_TUNNEL_LIST/name";
}
}

leaf mapname {
type string;
}

leaf vlan {
mandatory true;
type string {
pattern "Vlan(409[0-5]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[1-9])" {
error-message "Invalid Vlan name pattern";
error-app-tag vlan-name-invalid;
}
}
}

leaf vni {
mandatory true;
type uint32 {
range "1..16777215" {
error-message "VNI ID out of range";
error-app-tag vnid-invalid;
}
}
}
}
}

container EVPN_NVO {

list EVPN_NVO_LIST {

key "name";
max-elements 1;

leaf name {
type string;
}

leaf source_vtep {
mandatory true;
type leafref {
path "../../../VXLAN_TUNNEL/VXLAN_TUNNEL_LIST/name";
}
}
}
}
}

}
42 changes: 42 additions & 0 deletions src/CLI/actioner/README_cli_client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generic RESTful Python client

A generic RESTful Python client for interacting with JSON APIs.

## Usage

To use this client you just need to import ApiClient and initialize it with an URL endpoint

from cli_client import ApiClient
api = ApiClient('#your_api_endpoint') #your_api_endpoint is optional default is https://localhost:443

Now that you have a RESTful API object you can start sending requests.


## Making a request

The framework supports GET, PUT, POST, PATCH and DELETE requests:

from cli_client import ApiClient
api = ApiClient()
response = api.get('/authors/')
response = api.post('/authors/', {'title': 'Broadcom', 'author': 'Faraaz Mohammed'})
response = api.put('/author/faraaz/', {'dob': '06/09/2006'})
response = api.delete('/author/faraaz/')

## To get the Response Data
response = api.get('/authors/')
Use response.content object

For Successful request response.content will contain valid JSON data
For Non-Successful request response.content will contain errors object returned by REST Server

## Verifying Requests

Two helpers are built in to verify the success of requests made. `ok()` checks for a 20x status code and returns a boolean, `errors()` returns the body content as a dict object if the status code is not 20x:

response = api.get('/books/')
if response.ok():
print 'Success!'
else:
print req.errors()

119 changes: 119 additions & 0 deletions src/CLI/actioner/cli_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
################################################################################
# #
# Copyright 2019 Broadcom. The term Broadcom refers to Broadcom Inc. and/or #
# its subsidiaries. #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
# You may obtain a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
# #
################################################################################
import json
import urllib3

class ApiClient(object):
"""
A client for accessing a RESTful API
"""
def __init__(self, api_uri=None):
"""
Create a RESTful API client.
"""
api_uri="https://localhost:443"
self.api_uri = api_uri

self.checkCertificate = False

if not self.checkCertificate:
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

self.version = "0.0.1"

def set_headers(self, nonce = None):
from base64 import b64encode
from hashlib import sha256
from platform import platform, python_version
from hmac import new

if not nonce:
from time import time
nonce = int(time())

return {
'User-Agent': "PythonClient/{0} ({1}; Python {2})".format(self.version,
platform(True),
python_version())
}

@staticmethod
def merge_dicts(*dict_args):
result = {}
for dictionary in dict_args:
result.update(dictionary)

return result

def request(self, method, path, data = {}, headers = {}):
from requests import request

url = '{0}{1}'.format(self.api_uri, path)
params = {}
headers = self.merge_dicts(self.set_headers(), headers)

if method == "GET":
params.update(data)
return request(method, url, headers=headers, params=params, verify=self.checkCertificate)
else:
return request(method, url, headers=headers, params=params, data=json.dumps(data), verify=self.checkCertificate)

def post(self, path, data = {}):
return Response(self.request("POST", path, data, {'Content-Type': 'application/json'}))

def get(self, path, data = {}):
return Response(self.request("GET", path, data))

def put(self, path, data = {}):
return Response(self.request("PUT", path, data, {'Content-Type': 'application/json'}))

def patch(self, path, data = {}):
return Response(self.request("PATCH", path, data, {'Content-Type': 'application/json'}))

def delete(self, path, data = {}):
return Response(self.request("DELETE", path, data))

class Response(object):
def __init__(self, response):
self.response = response

try:
self.content = self.response.json()
except ValueError:
self.content = self.response.text

def ok(self):
import requests
return self.response.status_code == requests.codes.ok

def errors(self):
if self.ok():
return {}

errors = self.content

if(not isinstance(errors, dict)):
errors = {"error": errors} # convert to dict for consistency
elif('errors' in errors):
errors = errors['ietf-restconf:errors']

return errors

def __getitem__(self, key):
return self.content[key]
4 changes: 4 additions & 0 deletions src/CLI/actioner/sonic-cli-if.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ def run(func, args):

try:
# Temporary code for #show vlan command with dummy data
if func.__name__ == "get_openconfig_vlan_interfaces_interface_ethernet_switched_vlan_state":
api_response = {'Vlan100': {'Ethernet20': 'tagged', 'Ethernet40': 'untagged'}}
show_cli_output(args[0], api_response)
return
if body is not None:
api_response = getattr(aa,func.__name__)(*keypath, body=body)
else :
Expand Down
88 changes: 88 additions & 0 deletions src/CLI/actioner/sonic-cli-ptp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/python

import sys
import swsssdk
from rpipe_utils import pipestr
from scripts.render_cli import show_cli_output
from swsssdk import ConfigDBConnector

import urllib3
urllib3.disable_warnings()

PTP_CLOCK = 'PTP_CLOCK'
PTP_GLOBAL = 'GLOBAL'

if __name__ == '__main__':
pipestr().write(sys.argv)
db = swsssdk.SonicV2Connector(host='127.0.0.1')
db.connect(db.CONFIG_DB)
db.connect(db.COUNTERS_DB)

config_db = ConfigDBConnector()
if config_db is None:
sys.exit()
config_db.connect()
if sys.argv[1] == 'get_ietf_ptp_ptp_instance_list_default_ds':
raw_data = config_db.get_entry(PTP_CLOCK, PTP_GLOBAL)
api_response = {}
api_response['ietf-ptp:default-ds'] = raw_data
show_cli_output(sys.argv[3], api_response)
elif sys.argv[1] == 'get_ietf_ptp_ptp_instance_list_time_properties_ds':
print "Nothing"
sys.exit()
elif sys.argv[1] == 'get_ietf_ptp_ptp_instance_list_parent_ds':
print "Nothing"
sys.exit()
elif sys.argv[1] == 'get_ietf_ptp_ptp_instance_list_port_ds_list':
print "Nothing"
sys.exit()
elif sys.argv[1] == 'get_ietf_ptp_ptp_instance_list':
raw_data = config_db.get_keys(PTP_CLOCK)
api_response = {}
api_response_list = []
port_ds_dict = {}
port_ds_list = []
port_ds_entry = {}
for key in raw_data:
if "Ethernet" in key:
port_ds_entry = {}
port_ds_entry["port-number"] = key
port_ds_entry["port-state"] = "online"
port_ds_list.append(port_ds_entry)
port_ds_dict['port-ds-list'] = port_ds_list
api_response_list.append(port_ds_dict)
api_response['ietf-ptp:instance_list'] = api_response_list
show_cli_output(sys.argv[3], api_response)
elif sys.argv[1] == 'patch_ietf_ptp_ptp_instance_list_default_ds_domain_number':
data = {}
data['domain-number'] = sys.argv[3]
config_db.mod_entry(PTP_CLOCK, PTP_GLOBAL, data)
elif sys.argv[1] == 'patch_ietf_ptp_ptp_instance_list_default_ds_priority1':
data = {}
data['priority1'] = sys.argv[3]
config_db.mod_entry(PTP_CLOCK, PTP_GLOBAL, data)
elif sys.argv[1] == 'patch_ietf_ptp_ptp_instance_list_default_ds_priority2':
data = {}
data['priority2'] = sys.argv[3]
config_db.mod_entry(PTP_CLOCK, PTP_GLOBAL, data)
elif sys.argv[1] == 'patch_ietf_ptp_ptp_instance_list_default_ds_two_step_flag':
data = {}
if sys.argv[3] == "enable":
data['two-step-flag'] = '1'
else:
data['two-step-flag'] = '0'
config_db.mod_entry(PTP_CLOCK, PTP_GLOBAL, data)
elif sys.argv[1] == 'patch_ietf_ptp_ptp_transparent_clock_default_ds_delay_mechanism':
data = {}
data['tc-delay-mechanism'] = sys.argv[2]
config_db.mod_entry(PTP_CLOCK, PTP_GLOBAL, data)
elif sys.argv[1] == 'add_port':
data = {}
data['enable'] = '1'
config_db.set_entry(PTP_CLOCK, sys.argv[2], data)
elif sys.argv[1] == 'del_port':
config_db.set_entry(PTP_CLOCK, sys.argv[2], None)
else:
data = {}
data[sys.argv[1]] = sys.argv[2]
config_db.mod_entry(PTP_CLOCK, PTP_GLOBAL, data)
Loading

0 comments on commit e4744ef

Please sign in to comment.