잠재 고객과 고객에게 매우 기술적인 주제를 어떻게 가르치나요? 어떻게 하면 원활한 승차감을 얻을 수 있나요?
Isovalent에서는 사용자에게 최대한 원활한 학습 경험을 제공하기 위해 최선을 다하고 있습니다. Isovalent는 Kubernetes를 위한 사실상 클라우드 네트워킹 플랫폼인 Cilium의 창시자입니다. 우리는 네트워킹과 보안을 좋아하지만 사람들이 이를 어려운 주제로 생각할 수도 있다는 점에 감사드립니다. Kubernetes 네트워킹 학습을 재미있게 만들 수 있다고 생각하여 학습 경험을 게임화하는 것이 중요합니다.
Instruqt는 기술적으로 발전하고 사용자의 관심을 끌 수 있는 실습 랩을 구축할 수 있는 훌륭한 플랫폼을 제공합니다.
또한 우리는 사용자 경험이 원활해야 하고 프로세스가 완전히 자동화되어야 한다고 믿습니다.
다행히 Instruqt graphQL API를 활용하면 많은 작업을 수행할 수 있습니다.
이를 위해 우리는 자체 instruqt-go 라이브러리를 작성했으며 이를 오픈 소스로 결정했습니다. 이 라이브러리는 개발자가 Instruqt 플랫폼을 쉽게 자동화하고 통합할 수 있도록 설계되었습니다.
Instruqt 연구소를 게시할 때의 문제 중 하나는 Instruqt의 사용자 정보를 자체 데이터베이스 또는 CRM의 정보와 연결하는 것입니다.
이 첫 번째 게시물에서는 instruqt-go를 사용하여 다음과 같은 프록시를 구축하는 방법을 안내합니다.
그런 다음 Google Cloud Functions에 함수를 게시합니다.
연구소에서 사용자 정보를 수집하는 데는 다양한 이유가 있습니다.
사용자 데이터를 Instruqt 트랙에 전달하는 방법에는 여러 가지가 있습니다.
Instruqt 사용자 정의 매개변수는 트랙을 시작할 때 모든 종류의 정보를 전달하는 데 매우 유용합니다. 이러한 필드는 단순히 icp_ 접두사가 붙은 쿼리 매개변수로 URL에 추가됩니다. 이러한 매개변수는 Instruqt Webhook뿐만 아니라 Instruqt GraphQL API를 통해서도 검색할 수 있으므로 실용적으로 사용할 수 있습니다.
최근까지 Instruqt는 트랙 개발자에게 맞춤 매개변수를 사용하여 사용자 정보(예: 이름, 이메일 또는 토큰)를 전달하도록 권장했습니다.
그러나 맞춤 매개변수 사용에는 몇 가지 단점이 있습니다.
Instruqt 초대를 사용하면 트랙 목록을 만들고 쉽게 액세스할 수 있도록 사용자와 공유할 수 있는 초대 링크를 생성할 수 있습니다. 양식을 통해 사용자 데이터를 수집하도록 초대를 설정할 수 있습니다.
이 사용자 데이터는 Instruqt의 사용자 세부 정보에 추가됩니다(사용자 세부 정보는 사용자 계정에 첨부되지만 Instruqt 팀마다 고유합니다).
이는 워크숍에 매우 실용적이지만 몇 가지 제한 사항이 있습니다.
참고: Instruqt는 최근 랜딩 페이지를 조정할 수 있는 초대 형식인 랜딩 페이지를 도입했지만 동일한 장점과 한계를 가지고 있습니다.
최근 Instruqt는 사용자 정보를 전달하는 또 다른 방법을 추가했는데, 이는 이전 방법의 장점을 모두 결합한 것입니다.
암호화된 PII 방법을 사용하면 pii_tpg 쿼리 매개변수를 삽입 URL에 전달할 수 있습니다. 이는 다음을 의미합니다.
이 예에서는 이 새로운 방법을 사용할 것입니다. 이는 안전하고 신뢰할 수 있는 방식으로 Instruqt에 정보를 전달하는 것이 오늘날 가장 다재다능하기 때문입니다.
Wenn Sie eine Track-Seite auf Instruqt besuchen, besteht die Möglichkeit, den Track einzubetten.
Dadurch erhalten Sie eine URL, die ein für den Track eindeutiges Token enthält.
Die Verwendung dieser URL ist zwar völlig zulässig, bedeutet aber auch, dass jeder, der Zugriff auf dieses Token hat, den Track starten kann, wann immer er möchte.
Instruqt hat kürzlich einen API-Aufruf hinzugefügt, um einmalige Token für Tracks zu generieren, sodass URLs, die solche Token verwenden, nur einmal verwendet werden können.
Der Proxy, den wir codieren, wird einmalige Token verwenden, da wir Zugriff auf die API haben und diese problemlos generieren können.
Erstellen Sie zunächst ein Verzeichnis für Ihre Funktion:
mkdir instruqt-proxy
Gehen Sie in dieses Verzeichnis und initialisieren Sie die Go-Umgebung:
# Replace example.com with the prefix of your choice go mod init example.com/labs
Für lokale Tests erstellen Sie ein cmd-Verzeichnis:
mkdir cmd
Erstellen Sie in diesem Verzeichnis eine main.go-Datei mit folgendem Inhalt:
package main import ( "log" "os" // Blank-import the function package so the init() runs // Adapt if you replaced example.com earlier _ "example.com/labs" "github.com/GoogleCloudPlatform/functions-framework-go/funcframework" ) func main() { // Use PORT environment variable, or default to 8080. port := "8080" if envPort := os.Getenv("PORT"); envPort != "" { port = envPort } if err := funcframework.Start(port); err != nil { log.Fatalf("funcframework.Start: %v\n", err) } }
Zurück zum instruqt-proxy-Verzeichnis, erstellen Sie eine Proxy.go-Datei und fügen Sie ihr zunächst die Funktion init() zusammen mit den Go-Paketen hinzu, die wir verwenden werden:
package labs import ( "fmt" "net/http" "net/url" "os" "github.com/GoogleCloudPlatform/functions-framework-go/functions" "github.com/isovalent/instruqt-go/instruqt" ) func init() { functions.HTTP("InstruqtProxy", instruqtProxy) }
Dadurch können Google Cloud Functions die instruqtProxy-Funktion aufrufen, wenn sie initialisiert wird.
Lassen Sie uns diese Funktion schreiben:
const ( // Replace team name with yours instruqtTeam = "isovalent" ) func instruqtProxy(w http.ResponseWriter, r *http.Request) { instruqtToken := os.Getenv("INSTRUQT_TOKEN") if instruqtToken == "" { w.WriteHeader(http.StatusInternalServerError) return } instruqtClient := instruqt.NewClient(instruqtToken, instruqtTeam) // Get user from passed token utk := r.URL.Query().Get("utk") if utk == "" { w.WriteHeader(http.StatusUnauthorized) return } user, err := getUser(utk) if err != nil { w.WriteHeader(http.StatusUnauthorized) return } labSlug := r.URL.Query().Get("slug") url, err := getLabURL(instruqtClient, user, labSlug) if err != nil { w.WriteHeader(http.StatusNotFound) return } http.Redirect(w, r, url, http.StatusFound) }
In dieser Funktion:
Die getLabURL-Funktion generiert die Weiterleitungs-URL für das Labor basierend auf Benutzerinformationen, dem angeforderten Labor-Slug und dynamischen Informationen aus der Instruqt-API.
Lass es uns schreiben:
const ( // Replace with your sign-up page format labSignupPage = "https://isovalent.com/labs/%s" // Adapt to your values finishBtnText = "Try your next Lab!" finishBtnURL = "https://labs-map.isovalent.com/map?lab=%s&showInfo=true" ) func getLabURL(instruqtClient *instruqt.Client, u user, slug string) (string, error) { track, err := instruqtClient.GetTrackBySlug(slug) if err != nil { return "", err } // Unknown user if u.Email == "" { url := fmt.Sprintf(labSignupPage, slug) return url, nil } // Get one-time token token, err := instruqtClient.GenerateOneTimePlayToken(track.Id) if err != nil { return "", err } labURL, err := url.Parse(fmt.Sprintf("https://play.instruqt.com/embed/%s/tracks/%s", instruqtTeam, track.Slug)) if err != nil { return "", err } // Prepare the fields to encrypt encryptedPII, err := instruqtClient.EncryptUserPII(u.FirstName, u.LastName, u.Email) if err != nil { return "", err } // Add params params := map[string]string{ "token": token, "pii_tpg": encryptedPII, "show_challenges": "true", "finish_btn_target": "_blank", "finish_btn_text": finishBtnText, "finish_btn_url": fmt.Sprintf(finishBtnURL, track.Slug), } q := labURL.Query() for key, value := range params { q.Set(key, value) } // Encode the parameters labURL.RawQuery = q.Encode() return labURL.String(), nil }
Beachten Sie zunächst, dass wir einige neue Konstanten definiert haben, die Sie anpassen können:
Jetzt erklären wir die Schritte der getLabURL()-Funktion:
Das letzte Element, das in diesem Proxy fehlt, ist die Funktion getUser(). Ich kann Ihnen hier nicht viel weiterhelfen, da Sie in diesem Teil Ihre eigene Logik einsetzen. Möglicherweise verwenden Sie ein CRM wie Hubspot, um Kontaktinformationen aus der UTK oder einer anderen Datenbank abzurufen, es liegt an Ihnen!
Der Code, den ich Ihnen hier zeige, gibt einfach einen Beispielbenutzer zurück:
/* * This is where you add the logic to get user information from your CRM/database. */ type user struct { FirstName string LastName string Email string } func getUser(utk string) (u user, err error) { // Implement the logic to get your user information from UTK u = user{ FirstName: "John", LastName: "Doe", Email: "john@doe.com", } return u, err }
Jetzt, da wir unsere gesamte Proxy.go-Funktion haben, testen wir sie!
Aktualisieren Sie zunächst Ihre go.mod- und go.sum-Dateien mit:
go get ./... go mod tidy
Gehen Sie in Ihrem Instruqt-Dashboard zu „API-Schlüssel“ und rufen Sie den Wert Ihres API-Schlüssels ab. Exportieren Sie es als Variable in Ihre Shell:
export INSTRUQT_TOKEN=<your_instruqt_token>
Als nächstes starten Sie die Funktion auf Ihrem lokalen Computer:
FUNCTION_TARGET=InstruqtProxy go run ./cmd/main.go
Stellen Sie abschließend in einem anderen Terminal Testanfragen an localhost:8080, wo Ihre Funktion ausgeführt wird (Sie können oben eine PORT-Umgebungsvariable übergeben, um den Port bei Bedarf zu ändern):
curl -i "localhost:8080/?slug=cilium-getting-started&utk=someUtkValue"
Passen Sie es an, um einen Track Slug zu verwenden, der in Ihrer Instruqt-Organisation vorhanden ist. Wenn der Track existiert, sollten Sie eine 302-Antwort mit der Weiterleitungs-URL erhalten, die ein einmaliges Token für den Zugriff sowie die mit dem PII-Schlüssel verschlüsselten John Doe-Informationen und ein einmaliges Token (beginnend mit ott_) enthält!
Wenn Sie Docker verwenden möchten, um Ihre Funktion lokal zu testen, können Sie eine Docker-Datei in Ihrem aktuellen Verzeichnis erstellen:
FROM golang:1.23 WORKDIR /app COPY . . RUN go build -o myapp ./cmd/main.go ENV DEV=true ENV PORT=8080 EXPOSE $PORT CMD ["./myapp"]
Fügen Sie eine docker-compose.yaml-Datei hinzu:
version: '3' services: proxy: build: ./ ports: - "8080:8080" environment: INSTRUQT_TOKEN: ${INSTRUQT_TOKEN} FUNCTION_TARGET: InstruqtProxy
Zum Schluss erstellen und starten Sie Ihren Container:
docker-compose up --build
Und Sie können wie zuvor Anfragen an localhost:8080 senden!
In order to deploy to Google Cloud, first make sure you are logged in to your Google Cloud project:
gcloud auth application-default login
Next, let's create a new secret for the Instruqt token:
echo -n "$INSTRUQT_TOKEN" | gcloud secrets create instruqt-token --data-file=-
In order to adjust the permissions on this secret, you will need to get your project ID:
PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format="value(projectNumber)")
Then, add the "Secret Manager Secret Accessor" role for the default Compute Engine service account for the project:
gcloud secrets add-iam-policy-binding instruqt-token \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor"
Your secret is now ready to be used by the function!
You can then deploy the function (adapt the region if needed):
gcloud functions deploy "instruqt-proxy" \ --gen2 --runtime=go122 --region=europe-west1 --source=. \ --entry-point="InstruqtProxy" --trigger-http --allow-unauthenticated \ --set-secrets="INSTRUQT_TOKEN=instruqt-token:latest"
This will upload and build your project, and return the URL to access the function.
This URL will look something like https://europe-west1-
You can then test the function using that URL instead of localhost:8080!
This is a simplified approach to the lab proxy we use at Isovalent. There are things you might want to consider with this implementation:
This proxy can typically be used to give access to authenticated users in a safe way, while preserving user information in Instruqt reports and making sure embed URLs are not reusable.
Here is an example of usage of this proxy:
This can allow you to build a series of public sign-up pages for your labs, similar to what we have built on the Isovalent website. It can also be used to build a Kiosk interface, or even a more creative landing page such as the Cilium Labs map, where clicks on the map redirect to the lab proxy.
By making a complex networking technology like Cilium fun with our labs, we have made it the experience for users less intimidating and more approachable. Using our proxy can help you provide a similar user experience to your prospects. Please get in touch if you have any questions.
Atas ialah kandungan terperinci Memperkemaskan Akses kepada Makmal Instruqt Terbenam. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!