-
Notifications
You must be signed in to change notification settings - Fork 4.4k
[UI] - introduce Posthog for Vault Dedicated managed clusters #30425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
CI Results: |
Build Results: |
trackReplToggle = () => { | ||
this.analytics.trackEvent(TOGGLE_WEB_REPL); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an example of how to track custom events in the code.
We could also do something like {{on "click" (fn this.analytics.trackEvent MY_EVENT)}}
in the template, but I think the component file is a little cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is neat! Is the long-term plan to figure out where we want to add these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah! The plan is add event tracking to the toolkit for new features as we release them. It's something we can discuss with product and design as well. "How do we know this feature is successful?" can be answered with the data coming back from this work.
The first thing we're aiming to track is the reporting work, but all new features (and probably many old one) can be added as devs see fit!
ui/app/routes/vault/cluster.js
Outdated
const token = await this.api.auth.tokenLookUpSelf(); | ||
const entity = token.data.entity_id ? token.data.entity_id : `root_${crypto.randomUUID()}`; | ||
|
||
if (model.license?.state) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
License is only available to for ent customers, so do some guarding in case this somehow gets run in CE mode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is state just an empty string for CE cluster?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole model.license
is undefined. Which makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay, I was wondering if this should be mode?.license?.state
then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is neat! Excited to see the data from it. My main concern is with crypto.randomUUID
do to historical issues with it. The other suggestions are minor - like avoiding making an extra network request to lookup token data since we already should have that info after a user is auth'd.
Most everything else is a question because I'm trying to understand what's going on 😂
*/ | ||
|
||
/* | ||
Normally, the default export of this file would _do something_. In our case, the mthods for the provider simply log the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this comment was cut off - you left me on the edge of my seat! 🪑
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops! Fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a plan to add a readme?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was! Sorry I've been working on this PR over the course of like two months and I've definitely just forgotten some things. I'll remove this file for now and add real docs soon!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries at all! I'm just genuinely curious 😄
trackReplToggle = () => { | ||
this.analytics.trackEvent(TOGGLE_WEB_REPL); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is neat! Is the long-term plan to figure out where we want to add these?
ui/app/routes/vault/cluster.js
Outdated
try { | ||
let license; | ||
const token = await this.api.auth.tokenLookUpSelf(); | ||
const entity = token.data.entity_id ? token.data.entity_id : `root_${crypto.randomUUID()}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A while ago there was a bug (linked to this PR: #19410) because crypto.randomUUID()
requires secure context and so the UI broke for users accessing it in an insecure context. There was a whole back and forth about enforcing a secure context...because yes - Vault is a secure product 😅 . But essentially using uuid4()
(example) circumvents this issue all together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a whole back and forth about enforcing a secure context...because yes - Vault is a secure product 😅
Haha I have questions. But that's an easy swap!
ui/app/routes/vault/cluster.js
Outdated
const token = await this.api.auth.tokenLookUpSelf(); | ||
const entity = token.data.entity_id ? token.data.entity_id : `root_${crypto.randomUUID()}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you consider getting this from the auth service instead and save making another request?
this.auth.authData.entity_id
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can do!
'form-action': ["'none'"], | ||
}; | ||
|
||
policy['connect-src'].push('https://eu.i.posthog.com'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So does this happen regardless of whether analytics are enabled or not?
Also - what is this doing exactly? 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is enabled regardless. It's letting things connect to that posthog url from the web app.
Since the analytics client is inactive when running on HVD, this will be fine.
ENV.APP.ANALYTICS_CONFIG = { | ||
provider: 'posthog', | ||
enabled: true, | ||
project_id: 'phc_zPQ9fPlFj4ZTYKJmThG1C8AE4J4RgPQx8dJJ7agg4SG', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this id sensitive at all or something that we can have exposed like this? Sorry - no idea how this works 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope! These are the client side ids, so okay to have exposed/hardcoded.
}); | ||
|
||
module('#start', function () { | ||
skip('#start does nothing when no provider is given', function (assert) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a plan to un-skip these at some point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to test the start mechanism a differently than I got time for. I'll remove these for now and come back to them after code freeze
|
||
this.service.identifyUser(identifier, traits); | ||
|
||
assert.true(providerStub.identify.calledOnce, 'the service calls idenfiy on the provider'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert.true(providerStub.identify.calledOnce, 'the service calls idenfiy on the provider'); | |
assert.true(providerStub.identify.calledOnce, 'the service calls identfiy on the provider'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops
|
||
test('logging is not shown when inactive', function (assert) { | ||
this.service.debug = false; | ||
// for the next few lines, console.log WILL NOT WORK AS EXPECTED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😂 appreciate this comment
if (cr === null) return cr; | ||
const { properties } = cr; | ||
|
||
// extract ONLY what we need |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, would there ever be potential for Posthog adding a new field that they track that we could miss here? Or would that be gated behind an explicit upgrade of some sort?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question! My goal was to avoid that, so that's why I went for the "opt in" approach vs deleting the pieces we didn't want.
I destructured the properties we want from the original cr.properties
object, then rebuilt it a couple lines down without the other data points
* add dummy provider and wire it into the app * add tests for analytics service * add posthog provider * wire in posthog * add HVD limitation for analytics and add unit test * filter out sensitive event properties * add changelog * run copywrite headers * update logging tests for analytics service * update changelog format * disable telemetry in test mode * remove unnecessary test * self review * Update vault-reporting addon with analytics tracking changes * address review feedback --------- Co-authored-by: Jim Wright <[email protected]>
Description
This PR enables basic analytics tracking in the Web UI. We're using posthog as a provider, but only sending limited information back to the data warehouse. As written, this feature is only enabled on HVD managed clusters.
Implementation details
The activation of this feature is handled by two variables: (ember build)
environment
and theisHvdManaged
feature flag.analytics
) to the approute:application
)production
mode. Dev mode is purely for development purposesHow to test
ENABLE_POSTHOG=true yarn start
, this will run the app in development mode with an explicit call to send events to posthogent
vault backend.identify
- the service will send events even if you're not logged in. So try logging in with your root token or another user. This activity should be visible in the console.trackPageView
- we're collecting pageview information on every route transition. Navigating to any page will trigger this event. You can see the intended routename in the consoleurl
s as those can contain sensitive information on a user's Vault setup. This is intentionaltrackEvent
- custom events are triggered by user interactions. As an example, an event has been added to the REPL toggle button in the sidebar. Try toggling the REPL and note the message in the console.Enterprise tests pass? ✅
TODO only if you're a HashiCorp employee
backport/
label that matches the desired release branch. Note that in the CE repo, the latest release branch will look likebackport/x.x.x
, but older release branches will bebackport/ent/x.x.x+ent
.of a public function, even if that change is in a CE file, double check that
applying the patch for this PR to the ENT repo and running tests doesn't
break any tests. Sometimes ENT only tests rely on public functions in CE
files.
in the PR description, commit message, or branch name.
description. Also, make sure the changelog is in this PR, not in your ENT PR.