Skip to content

Commit

Permalink
Merge pull request #69 from openziti/add-appetizer-reflect-demo
Browse files Browse the repository at this point in the history
Add appetizer reflect demo
  • Loading branch information
dovholuknf authored Feb 27, 2024
2 parents 1839a71 + 0126675 commit 5bd4f7e
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 12 deletions.
53 changes: 53 additions & 0 deletions OpenZiti.NET.Samples/src/Appetizer/AppetizerSample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
Copyright NetFoundry Inc.
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
https://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.
*/

using OpenZiti.Management;
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

using OpenZiti.NET.Samples.Common;
using System.Security.Principal;
using System.Reflection.PortableExecutable;
using System.Net.Sockets;
using OpenZiti.NET.Samples.src.Common;

namespace OpenZiti.NET.Samples.Appetizer {

[Sample("appetizer-reflect")]
public class AppetizerSample : SampleBase {
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
internal const string REFLECT_SERVICE_NAME = "reflectService";

public override async Task<object> RunAsync(string[] args) {
Log.Info("Appetizer reflect demo starts");
var zitiContext = AppetizerSetup.ContextFromFile(args[1]);
using Stream stream = ZitifiedNetworkStream.NewStream(zitiContext, REFLECT_SERVICE_NAME, null);
using var reader = new StreamReader(stream, Encoding.ASCII);
using var writer = new StreamWriter(stream, Encoding.ASCII);
while (true) {
Console.Write("Enter some text to send: ");
var input = Console.ReadLine();
await writer.WriteAsync(input);
await writer.FlushAsync();
var response = await reader.ReadLineAsync();
Console.WriteLine($"Received: {response}");
} //this just loops forever and c# is smart enough not to need a 'return' -- neat
}
}
}
36 changes: 36 additions & 0 deletions OpenZiti.NET.Samples/src/Appetizer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Appetizer - reflect server

This sample demonstrates how to write data to a stream and receive data. It uses the https://openziti.io/appetizer
demonstration environment which is capable of genearting an identity for you, to be used with this sample. It
utilizes the reflect server functionality to return whatever data you send to the server back to you. The reflect
server also is tied to an LLM which is attempting to classify your input. If you use something that seems "hateful"
you will receive an error message indicating your input was not accepted. The server is written in go and the
source for the server is available at https://github.com/openziti-test-kitchen/appetizer.

## OpenZiti Concepts Demonstrated

This sample demonstrates some key OpenZiti concepts:

* Application-embedded zero trust client written in C# to a golang-based application embedded zero trust server.
* Sending data in a line-delimeted protocol to a server deployed out in the cloud, then receiving and displaying
the response.
* Directly dialing a service by service name, in this case it is named "reflectService"
* Creating a a strong identity by enrolling a one-time use token provided by the appetizer server.

## Setup

This sample is unlike others. It relies on an instance of the appetizer demo to be deployed. It's easiest to use
the instance OpenZiti has deployed by going to https://appetizer.openziti.io/. You'll see a screen asking you to
enter something unique, like your email address. There's a button to click named "Add to OpenZiti". After you click
the button, you'll be able to save/download a one-time use token.

To run the sample, simply provide the path to that token as a argument to the program.

## Running the Sample

After downloading the .jwt, you should be able to just run it directly.

Example:
```
dotnet run --project OpenZiti.NET.Samples/OpenZiti.NET.Samples.csproj appetizer-reflect
```
44 changes: 44 additions & 0 deletions OpenZiti.NET.Samples/src/Common/AppetizerSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright NetFoundry Inc.
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
https://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.
*/

using System.IO;
using System.Text;

namespace OpenZiti.NET.Samples.src.Common;
internal class AppetizerSetup {
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
internal static ZitiContext ContextFromFile(string idFile) {
if (idFile.EndsWith(".json")) {
// good - we'll just use it
} else if (idFile.EndsWith(".jwt")) {
// infer it's a jwt to be enrolled... strip .jwt and find a .json and use THAT if it's here...
var idFileJson = idFile.Replace(".jwt", ".json");
if (File.Exists(idFileJson)) {
// use it
idFile = idFileJson;
} else {
// assume we need to enroll the file
Log.Info($"{idFileJson} doesn't exist. Assuming this is a token to enroll...");

var strongIdentity = API.EnrollIdentityFile(idFile);
File.WriteAllBytes($"{idFileJson}", Encoding.UTF8.GetBytes(strongIdentity));
Log.Info($"Strong identity written to: {idFileJson}");
idFile = idFileJson;
}
}

var idFileBytes = File.ReadAllText(idFile);
var c = new ZitiContext(idFileBytes); //demonstrates loading an identity via json, not as a file
return c;
}
}
5 changes: 4 additions & 1 deletion OpenZiti.NET.Samples/src/Common/SampleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ public static void Enroll(string pathToEnrollmentToken, string outputPath) {
Log.Info($"Strong identity enrolled successfully. File saved to: {outputPath}");
}

public abstract Task<object> RunAsync();
public virtual Task<object> RunAsync() {
return RunAsync(null);
}
public abstract Task<object> RunAsync(string[] args);
}

[AttributeUsage(AttributeTargets.Class)]
Expand Down
2 changes: 1 addition & 1 deletion OpenZiti.NET.Samples/src/Enrollment/Enrollment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace OpenZiti.NET.Samples {

public class EnrollmentSample : SampleBase {
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
public override async Task<object> RunAsync() {
public override async Task<object> RunAsync(string[] args) {
Log.Info("EnrollmentSample starts");
var enrollDemoIdentityName = "enroll-demo";
var s = new SampleSetup();
Expand Down
2 changes: 1 addition & 1 deletion OpenZiti.NET.Samples/src/PetStore/PetstoreSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace OpenZiti.NET.Samples.Weather {
public class PetstoreSample : SampleBase {
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();

public override async Task<object> RunAsync() {
public override async Task<object> RunAsync(string[] args) {
Log.Info("PetstoreSample starts");
var svcName = "petstore-demo-svc";
var desiredIntercept = "my.petstore";
Expand Down
7 changes: 1 addition & 6 deletions OpenZiti.NET.Samples/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ private static async Task Main(string[] args) {
SampleSetup.Initialize = (args[1]?.ToLower().Trim() != "noinit");
if (args.Length > 2) {
SampleSetup.IdentityFile = args[2];
} else {
throw new Exception(
@"when using 'noint', you must supply an identity file to use as the third parameter
Example:
dotnet run --project OpenZiti.NET.Samples/OpenZiti.NET.Samples.csproj weather noinit /my/identity.file");
}
} else {
SampleSetup.Initialize = true;
Expand All @@ -67,7 +62,7 @@ private static async Task Main(string[] args) {
var attr = (Sample)Attribute.GetCustomAttribute(type, typeof(Sample));
if (attr?.Name == args[0]) {
var sample = (SampleBase)Activator.CreateInstance(type);
await sample.RunAsync();
await sample.RunAsync(args);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace OpenZiti.NET.Samples {
[Sample("hosted-client")]
public class HostedServiceClientSample : SampleBase {
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
public override async Task<object> RunAsync() {
public override async Task<object> RunAsync(string[] args) {
Log.Info("HostedServiceClientSample starts");
//to see the logs from the Native SDK, set the log level
API.SetLogLevel(ZitiLogLevel.INFO);
Expand Down
2 changes: 1 addition & 1 deletion OpenZiti.NET.Samples/src/Server/HostedServiceSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace OpenZiti.NET.Samples.Server {
[Sample("hosted")]
public class HostedServiceSample : SampleBase {
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();
public override async Task<object> RunAsync() {
public override async Task<object> RunAsync(string[] args) {
Log.Info("HostedServiceClientSample starts");
//to see the logs from the Native SDK, set the log level
API.SetLogLevel(ZitiLogLevel.INFO);
Expand Down
2 changes: 1 addition & 1 deletion OpenZiti.NET.Samples/src/Weather/WeatherSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace OpenZiti.NET.Samples.Weather {
public class WeatherSample : SampleBase {
private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();

public override async Task<object> RunAsync() {
public override async Task<object> RunAsync(string[] args) {
Log.Info("WeatherSample starts");
var svcName = "weather-demo-svc";
var setupResult = await new SampleSetup(new()).SetupWeatherExample(svcName);
Expand Down

0 comments on commit 5bd4f7e

Please sign in to comment.