@@ -29,6 +29,10 @@ var card *notecard.Context
2929// CLI Version - Set by ldflags during build/release
3030var version = "development"
3131
32+ // JSON schema control variables
33+ var validateJSON bool = false
34+ var jsonSchemaUrl string = "https://raw.githubusercontent.com/blues/notecard-schema/master/notecard.api.json"
35+
3236// getFlagGroups returns the organized flag groups
3337func getFlagGroups () []lib.FlagGroup {
3438 return []lib.FlagGroup {
@@ -66,7 +70,6 @@ func getFlagGroups() []lib.FlagGroup {
6670 lib .GetFlagByName ("output" ),
6771 lib .GetFlagByName ("fast" ),
6872 lib .GetFlagByName ("trace" ),
69- lib .GetFlagByName ("force" ),
7073 },
7174 },
7275 {
@@ -108,7 +111,6 @@ func getFlagGroups() []lib.FlagGroup {
108111 lib .GetFlagByName ("interface" ),
109112 lib .GetFlagByName ("port" ),
110113 lib .GetFlagByName ("portconfig" ),
111- lib .GetFlagByName ("json-schema-url" ),
112114 },
113115 },
114116 {
@@ -144,6 +146,13 @@ func main() {
144146 os .Exit (exitFail )
145147 }()
146148
149+ // Check the environment for JSON schema control variables
150+ _ , validateJSON = os .LookupEnv ("BLUES" ) // Opt-in Blues employees to validation
151+ url := os .Getenv ("NOTE_JSON_SCHEMA_URL" ) // Override the default schema URL
152+ if url != "" {
153+ jsonSchemaUrl = url
154+ }
155+
147156 // Override the default usage function to use our grouped format
148157 flag .Usage = func () {
149158 lib .PrintGroupedFlags (getFlagGroups (), "notecard" )
@@ -162,8 +171,6 @@ func main() {
162171 flag .BoolVar (& actionWhenDisarmed , "when-disarmed" , false , "wait until ATTN is disarmed" )
163172 var actionVerbose bool
164173 flag .BoolVar (& actionVerbose , "verbose" , false , "display Notecard requests and responses" )
165- var actionForce bool
166- flag .BoolVar (& actionForce , "force" , false , "bypass JSON request validation against the Notecard schema (when used with -req)" )
167174 var actionWhenSynced bool
168175 flag .BoolVar (& actionWhenSynced , "when-synced" , false , "sync if needed and wait until sync completed" )
169176 var actionReserved bool
@@ -678,48 +685,41 @@ func main() {
678685 actionRequest = ""
679686 }
680687
681- // If the user has provided a JSON schema URL, we need to clear the cache
682- // and re-initialize the schema. This is because the schema URL may have
683- // changed, and we need to make sure that the schema is up to date.
684- json_provided := false
685- for _ , arg := range os .Args {
686- if arg == "-json-schema-url" {
687- json_provided = true
688- break
689- }
690- }
691- if err == nil && json_provided {
692- clearCache ()
693- url := lib .Config .SchemaUrl
694- if url == "" {
695- url = defaultJsonSchemaUrl
696- }
697- err = initSchema (url )
698- }
699-
700688 if err == nil && actionRequest != "" {
701689 var rspJSON []byte
702690 var req , rsp notecard.Request
703691 note .JSONUnmarshal ([]byte (actionRequest ), & req )
704692
705- if ! actionForce {
706- err = validateRequest ([]byte (actionRequest ), lib .Config .SchemaUrl )
707- if err != nil {
708- goto done
709- }
710- }
711-
712- // If we want to read the payload from a file, do so
693+ // Append payload from the specified file
713694 if actionInput != "" {
714695 var contents []byte
715696 contents , err = os .ReadFile (actionInput )
716697 if err == nil {
717698 req .Payload = & contents
699+
700+ // Update the original request with the payload
701+ var reqBytes []byte
702+ reqBytes , err = note .JSONMarshal (req )
703+ if err == nil {
704+ actionRequest = string (reqBytes )
705+ }
706+ }
707+ }
708+
709+ // Validate the request against the schema
710+ if err == nil && validateJSON {
711+ var reqMap map [string ]interface {}
712+ err = note .JSONUnmarshal ([]byte (actionRequest ), & reqMap )
713+ if err == nil {
714+ validationErr := validateRequest (reqMap , jsonSchemaUrl , actionVerbose )
715+ if validationErr != nil {
716+ fmt .Fprintf (os .Stderr , "warning: %s\n " , validationErr )
717+ }
718718 }
719719 }
720720
721721 // Perform the transaction and do special handling for binary
722- if req .Req == "card.binary.get" {
722+ if err == nil && req .Req == "card.binary.get" {
723723 expectedMD5 := req .Status
724724 rsp , err = card .TransactionRequest (req )
725725 if err == nil {
@@ -739,7 +739,7 @@ func main() {
739739 }
740740 }
741741 }
742- } else if req .Req == "card.binary.put" && (req .Body == nil || len (* req .Body ) == 0 ) {
742+ } else if err == nil && req .Req == "card.binary.put" && (req .Body == nil || len (* req .Body ) == 0 ) {
743743 payload := * req .Payload
744744 actualMD5 := fmt .Sprintf ("%x" , md5 .Sum (payload ))
745745 if req .Status != "" && ! strings .EqualFold (req .Status , actualMD5 ) {
@@ -757,7 +757,8 @@ func main() {
757757 }
758758 }
759759 }
760- } else {
760+ } else if err == nil {
761+ // Transact using CLI input to avoid JSON parsing complications
761762 actionRequest = strings .ReplaceAll (actionRequest , "\\ n" , "\n " )
762763 rspJSON , err = card .TransactionJSON ([]byte (actionRequest ))
763764 if err == nil {
@@ -766,25 +767,23 @@ func main() {
766767 }
767768
768769 // Write the payload to an output file if appropriate
769- if err == nil && actionOutput != "" {
770- if rsp .Payload != nil {
771- err = os . WriteFile ( actionOutput , * rsp . Payload , 0644 )
772- if err != nil {
773- rsp . Payload = nil
774- }
770+ if err == nil && actionOutput != "" && rsp . Payload != nil {
771+ err = os . WriteFile ( actionOutput , * rsp .Payload , 0644 )
772+ // If we can't write the file, set the payload to nil so
773+ // we don't try to print it out and cause a JSON error.
774+ if err ! = nil {
775+ rsp . Payload = nil
775776 }
776777 }
777778
778779 // Output the response to the console
779- if ! actionVerbose {
780- if err == nil {
781- if actionPretty {
782- rspJSON , _ = note .JSONMarshalIndent (rsp , "" , " " )
783- } else {
784- rspJSON , _ = note .JSONMarshal (rsp )
785- }
786- fmt .Printf ("%s\n " , rspJSON )
780+ if err == nil && ! actionVerbose {
781+ if actionPretty {
782+ rspJSON , _ = note .JSONMarshalIndent (rsp , "" , " " )
783+ } else {
784+ rspJSON , _ = note .JSONMarshal (rsp )
787785 }
786+ fmt .Printf ("%s\n " , rspJSON )
788787 }
789788 }
790789
@@ -854,7 +853,6 @@ func main() {
854853 err = explore (actionReserved , actionPretty )
855854 }
856855
857- done:
858856 // Process errors
859857 if err != nil {
860858 if actionRequest != "" && ! actionVerbose {
0 commit comments