Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions models/yang/annotations/openconfig-system-annot.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module openconfig-system-annot {

yang-version "1";

namespace "http://openconfig.net/yang/openconfig-system-annot";
prefix "oc-sys-annot";

import openconfig-system { prefix oc-sys; }
import sonic-extensions {prefix sonic-ext; }
import openconfig-system-grpc { prefix oc-sys-grpc; }

deviation /oc-sys:system/oc-sys:ssh-server/oc-sys:state {
deviate add {
sonic-ext:db-name "STATE_DB";
sonic-ext:subtree-transformer "ssh_server_state_xfmr";
}
}

deviation /oc-sys:system/oc-sys-grpc:grpc-servers {
deviate add {
sonic-ext:key-transformer "grpc_server_key_xfmr";
sonic-ext:subtree-transformer "grpc_server_xfmr";
}
}
}

2 changes: 1 addition & 1 deletion translib/transformer/subscribe_req_xlate.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ func (pathXltr *subscribePathXlator) handleSubtreeNodeXlate() error {
log.Info(pathXltr.subReq.reqLogId, "handleSubtreeNodeXlate: handleSubtreeNodeXlate: uriSubtree: ", uriSubtree)
}

subInParam := XfmrSubscInParams{uriSubtree, pathXltr.subReq.dbs, make(RedisDbMap), TRANSLATE_SUBSCRIBE}
subInParam := XfmrSubscInParams{uri: uriSubtree, requestURI: pathXltr.subReq.reqUri, dbs: pathXltr.subReq.dbs, dbDataMap: make(RedisDbMap), subscProc: TRANSLATE_SUBSCRIBE}
subOutPram, subErr := xfmrSubscSubtreeHandler(subInParam, ygXpathInfo.xfmrFunc)

if log.V(dbLgLvl) {
Expand Down
9 changes: 5 additions & 4 deletions translib/transformer/xfmr_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ type notificationOpts struct {

// XfmrSubscInParams represents input to subscribe subtree callbacks - request uri, DBs info access-pointers, DB info for request uri and subscription process type from translib.
type XfmrSubscInParams struct {
uri string
dbs [db.MaxDB]*db.DB
dbDataMap RedisDbMap
subscProc SubscProcType
uri string
requestURI string
dbs [db.MaxDB]*db.DB
dbDataMap RedisDbMap
subscProc SubscProcType
}

// XfmrSubscOutParams represents output from subscribe subtree callback - DB data for request uri, Need cache, OnChange, subscription preference and interval.
Expand Down
301 changes: 301 additions & 0 deletions translib/transformer/xfmr_system.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
package transformer

import (
"errors"
"fmt"
"strconv"
"strings"

"github.com/Azure/sonic-mgmt-common/translib/db"
"github.com/Azure/sonic-mgmt-common/translib/ocbinds"
log "github.com/golang/glog"
ygot "github.com/openconfig/ygot/ygot"
)

const (
GNXI_ID = "gnxi"

/** Credential Tables **/
CREDENTIALS_TBL = "CREDENTIALS"
CRED_PATHZ_TBL = "CREDENTIALS|PATHZ_POLICY"
CERT_TBL = "CREDENTIALS|CERT"
)

type sshState struct {
caKeys certData
hostCert certData
hostKey certData
counters accessCounters
}

type accessCounters struct {
accessRejects uint64
lastAccessReject uint64
accessAccepts uint64
lastAccessAccept uint64
}

type certData struct {
version string
created uint64
}

func init() {
XlateFuncBind("DbToYang_grpc_server_xfmr", DbToYang_grpc_server_xfmr)
XlateFuncBind("Subscribe_grpc_server_xfmr", Subscribe_grpc_server_xfmr)
XlateFuncBind("DbToYang_grpc_server_key_xfmr", DbToYang_grpc_server_key_xfmr)
XlateFuncBind("DbToYang_ssh_server_state_xfmr", DbToYang_ssh_server_state_xfmr)
XlateFuncBind("Subscribe_ssh_server_state_xfmr", Subscribe_ssh_server_state_xfmr)
}

type grpcState struct {
name string
certVersion string
certCreated uint64
caVersion string
caCreated uint64
crlVersion string
crlCreated uint64
authPolVersion string
authPolCreated uint64
profileId string
pathzVersion string
pathzCreated uint64
}

func getAppRootObject(inParams XfmrParams) *ocbinds.OpenconfigSystem_System {
deviceObj := (*inParams.ygRoot).(*ocbinds.Device)
return deviceObj.System
}

func getAllKeys(sdb *db.DB, tblName string) ([]string, error) {
tbl, err := sdb.GetTable(&db.TableSpec{Name: tblName})
if err != nil {
return nil, fmt.Errorf("Can't get table: %v, err: %v", tblName, err)
}
log.V(3).Infof("tbl: %v", tbl)
keys, err := tbl.GetKeys()
if err != nil {
return nil, fmt.Errorf("Can't get keys from %v, err: %v", tblName, err)
}
log.V(3).Infof("tbl keys: %v", keys)
ret := []string{}
for _, key := range keys {
if len(key.Comp) != 3 {
// This is a phantom key. Ignore it.
continue
}
ret = append(ret, key.Comp[2])
}
log.V(3).Infof("keys: %v", ret)
return ret, nil
}

var Subscribe_ssh_server_state_xfmr SubTreeXfmrSubscribe = func(inParams XfmrSubscInParams) (XfmrSubscOutParams, error) {
log.V(3).Infof("Subscribe_ssh_server_state_xfmr:%s", inParams.requestURI)

return XfmrSubscOutParams{
dbDataMap: RedisDbSubscribeMap{
db.StateDB: {"CREDENTIALS": {"SSH_HOST": {}}}},
onChange: OnchangeEnable,
nOpts: &notificationOpts{mInterval: 0, pType: OnChange},
}, nil
}

var DbToYang_ssh_server_state_xfmr SubTreeXfmrDbToYang = func(inParams XfmrParams) error {
var state sshState

table, err := inParams.dbs[inParams.curDb].GetEntry(&db.TableSpec{Name: "CREDENTIALS"}, db.Key{Comp: []string{"SSH_HOST"}})
if err != nil {
log.V(3).Infof("Failed to read from StateDB: %v", inParams.table)
return err
}

state.caKeys.version = table.Get("ca_keys_version")
time := table.Get("ca_keys_created_on")
if state.caKeys.created, err = strconv.ParseUint(time, 10, 64); err != nil && time != "" {
log.V(0).Infof("Couldn't find ca_keys_created_on: %v", err)
}
state.hostKey.version = table.Get("host_key_version")
time = table.Get("host_key_created_on")
if state.hostKey.created, err = strconv.ParseUint(time, 10, 64); err != nil && time != "" {
log.V(0).Infof("Couldn't find host_key_created_on: %v", err)
}
state.hostCert.version = table.Get("host_cert_version")
time = table.Get("host_cert_created_on")
if state.hostCert.created, err = strconv.ParseUint(time, 10, 64); err != nil && time != "" {
log.V(0).Infof("Couldn't find host_cert_created_on: %v", err)
}
accepts := table.Get("access_accepts")
if state.counters.accessAccepts, err = strconv.ParseUint(accepts, 10, 64); err != nil && accepts != "" {
log.V(0).Infof("Couldn't find access_accepts: %v", err)
}
lastAccept := table.Get("last_access_accept")
if state.counters.lastAccessAccept, err = strconv.ParseUint(lastAccept, 10, 64); err != nil && lastAccept != "" {
log.V(0).Infof("Couldn't find last_access_accept: %v", err)
}
rejects := table.Get("access_rejects")
if state.counters.accessRejects, err = strconv.ParseUint(rejects, 10, 64); err != nil && rejects != "" {
log.V(0).Infof("Couldn't find access_rejects: %v", err)
}
lastReject := table.Get("last_access_reject")
if state.counters.lastAccessReject, err = strconv.ParseUint(lastReject, 10, 64); err != nil && lastReject != "" {
log.V(0).Infof("Couldn't find last_access_reject: %v", err)
}

sysObj := getAppRootObject(inParams)
ygot.BuildEmptyTree(sysObj.SshServer.State)

sysObj.SshServer.State.ActiveTrustedUserCaKeysCreatedOn = &state.caKeys.created
sysObj.SshServer.State.ActiveTrustedUserCaKeysVersion = &state.caKeys.version
sysObj.SshServer.State.ActiveHostCertificateCreatedOn = &state.hostKey.created
sysObj.SshServer.State.ActiveHostCertificateVersion = &state.hostKey.version
sysObj.SshServer.State.ActiveHostKeyCreatedOn = &state.hostCert.created
sysObj.SshServer.State.ActiveHostKeyVersion = &state.hostCert.version
sysObj.SshServer.State.Counters.AccessAccepts = &state.counters.accessAccepts
sysObj.SshServer.State.Counters.AccessRejects = &state.counters.accessRejects
sysObj.SshServer.State.Counters.LastAccessAccept = &state.counters.lastAccessAccept
sysObj.SshServer.State.Counters.LastAccessReject = &state.counters.lastAccessReject

return nil
}

var Subscribe_grpc_server_xfmr SubTreeXfmrSubscribe = func(inParams XfmrSubscInParams) (XfmrSubscOutParams, error) {
pathInfo := NewPathInfo(inParams.uri)
serverName := pathInfo.Var("name")
targetUriPath, err := getYangPathFromUri(pathInfo.Path)
if err != nil {
return XfmrSubscOutParams{}, err
}
log.V(3).Infof("Subscribe_grpc_server_xfmr: targetUriPath: %s name: %s", targetUriPath, serverName)

var result XfmrSubscOutParams
if serverName == "" {
result.dbDataMap = RedisDbSubscribeMap{
db.StateDB: map[string]map[string]map[string]string{
CREDENTIALS_TBL: {
"CERT|gnxi": {},
},
},
}
} else {
result = XfmrSubscOutParams{
dbDataMap: RedisDbSubscribeMap{
db.StateDB: map[string]map[string]map[string]string{
CREDENTIALS_TBL: {
"CERT|gnxi": {},
},
}},
}
}

if !strings.HasPrefix(targetUriPath, "/openconfig-system:system/grpc-servers/grpc-server/gnsi-pathz:gnmi-pathz-policy-counters") {
Comment thread
jayaragini-hcl marked this conversation as resolved.
result.onChange = OnchangeEnable
result.nOpts = &notificationOpts{mInterval: 0, pType: OnChange}
} else {

// For counters, configure nOpts to enable sampling on path.
result.onChange = OnchangeEnable
result.nOpts = &notificationOpts{mInterval: 60, pType: Sample}
}
return result, nil
}

var DbToYang_grpc_server_xfmr SubTreeXfmrDbToYang = func(inParams XfmrParams) error {
pathInfo := NewPathInfo(inParams.uri)
serverNames := []string{pathInfo.Var("name")}
if log.V(3) {
log.Info("SubtreeXfmrFunc - Uri SYS AUTH: ", inParams.uri)
log.Info("names:", serverNames)
}
stateDb := inParams.dbs[db.StateDB]
if stateDb == nil {
return errors.New("DbToYang_grpc_server_xfmr stateDb is nil!")
}
if len(serverNames) == 0 || len(serverNames[0]) == 0 {
var err error
if serverNames, err = getAllKeys(stateDb, CERT_TBL); err != nil {
return err
}
}
sysObj := getAppRootObject(inParams)
ygot.BuildEmptyTree(sysObj)
ygot.BuildEmptyTree(sysObj.GrpcServers)

for _, serverName := range serverNames {
log.V(3).Info("serverName: ", serverName)
var state grpcState
state.name = serverName

certzID := GNXI_ID
certTable, err := stateDb.GetEntry(&db.TableSpec{Name: CERT_TBL}, db.Key{Comp: []string{certzID}})
if err != nil {
log.V(0).Infof("Failed to read from StateDB %v | %v err: %v", CERT_TBL, certzID, err)
} else {
state.certVersion = certTable.Get("certificate_version")
state.caVersion = certTable.Get("ca_trust_bundle_version")
state.crlVersion = certTable.Get("certificate_revocation_list_bundle_version")
state.authPolVersion = certTable.Get("authentication_policy_version")
state.profileId = certTable.Get("ssl_profile_id")
time := certTable.Get("certificate_created_on")
if state.certCreated, err = strconv.ParseUint(time, 10, 64); err != nil && time != "" {
log.V(0).Infof("Cannot convert `certificate_created_on` for %v, err: %v", certzID, err)
}
time = certTable.Get("ca_trust_bundle_created_on")
if state.caCreated, err = strconv.ParseUint(time, 10, 64); err != nil && time != "" {
log.V(0).Infof("Cannot convert `ca_trust_bundle_created_on` for %v, err: %v", certzID, err)
}
time = certTable.Get("certificate_revocation_list_bundle_created_on")
if state.crlCreated, err = strconv.ParseUint(time, 10, 64); err != nil && time != "" {
log.V(0).Infof("Cannot convert `certificate_revocation_list_bundle_created_on` for %v, err: %v", certzID, err)
}
time = certTable.Get("authentication_policy_created_on")
if state.authPolCreated, err = strconv.ParseUint(time, 10, 64); err != nil && time != "" {
log.V(0).Infof("Cannot convert `authentication_policy_created_on` for %v, err: %v", certzID, err)
}
}

pathzTable, err := stateDb.GetEntry(&db.TableSpec{Name: CRED_PATHZ_TBL}, db.Key{Comp: []string{"ACTIVE"}})
if err != nil {
log.V(0).Infof("Failed to read from StateDB %v, err: %v", CRED_PATHZ_TBL, err)
} else {
state.pathzVersion = pathzTable.Get("pathz_version")
if timeStr := pathzTable.Get("pathz_created_on"); timeStr != "" {
if state.pathzCreated, err = strconv.ParseUint(timeStr, 10, 64); err != nil {
log.V(0).Infof("Cannot convert `pathz_created_on` for %v, err: %v", serverName, err)
}
}
}

serverObj, ok := sysObj.GrpcServers.GrpcServer[serverName]
if !ok {
serverObj, err = sysObj.GrpcServers.NewGrpcServer(serverName)
if err != nil {
log.V(0).Infof("sysObj.GrpcServers.NewGrpcServer(%v) failed: %v", serverName, err)
continue
}
}
ygot.BuildEmptyTree(serverObj)
serverObj.State.Name = &state.name
serverObj.State.CaTrustBundleVersion = &state.caVersion
serverObj.State.CaTrustBundleCreatedOn = &state.caCreated
serverObj.State.CertificateVersion = &state.certVersion
serverObj.State.CertificateCreatedOn = &state.certCreated
serverObj.State.CertificateRevocationListBundleCreatedOn = &state.crlCreated
serverObj.State.CertificateRevocationListBundleVersion = &state.crlVersion
serverObj.State.AuthenticationPolicyVersion = &state.authPolVersion
serverObj.State.SslProfileId = &state.profileId
serverObj.State.AuthenticationPolicyCreatedOn = &state.authPolCreated
serverObj.State.GnmiPathzPolicyCreatedOn = &state.pathzCreated
serverObj.State.GnmiPathzPolicyVersion = &state.pathzVersion

}

return nil
}

var DbToYang_grpc_server_key_xfmr KeyXfmrDbToYang = func(inParams XfmrParams) (map[string]interface{}, error) {
log.V(3).Info("DbToYang_grpc_server_key_xfmr root, uri: ", inParams.ygRoot, inParams.uri)

return map[string]interface{}{"name": NewPathInfo(inParams.uri).Var("name")}, nil
}