-
Notifications
You must be signed in to change notification settings - Fork 0
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
Implement exporterfactory #4
Conversation
Got some clarification that the factory should also handle the other exporters. Will update to reflect that |
sdk/Trace/ExporterFactory.php
Outdated
public function fromConnectionString(string $configurationString) | ||
{ | ||
$strArr = explode('+', $configurationString); | ||
$contribName = $strArr[0]; |
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 should be validated against an allowlist. This is untrusted user input and needs to be validated. Since we know the allowable values here an allowlist should be used to reject any non-allowed values. My PHP is incredibly rusty, but something like this should work:
private $_allowedExporters = array("Jaeger" => true, "Zipkin" => true);
private function _isAllowed(string $exporter)
{
return array_key_exists($this->_allowedExporters, $exporter) && $this->_allowedExporters{$exporter};
}
...
$contribName = ucfirst(lower($strArr[0]));
if !$this->_isAllowed($contribName) {
return null // or some way to indicate an error here
}
$dynamicExporter = ...
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 agree with Aneurysm9, you must always sanitize any user input to protect from attacks. If we do have an allowed exporters list, then definitely use that as suggested.
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.
Also look into the htmlentities() function which could serve as a way to sanitize input. Make sure it is relevant to your issue, usually it is used mostly to protect from front end malicious input.
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.
Thanks for these reviews. Will soon have an update to reflect this
/** | ||
* @test | ||
*/ | ||
public function testIfExporterHasCorrectEndpoint() |
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.
Be sure to add a test for invalid input as well. Perhaps even malicious input if you can construct one.
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.
When writing you tests, make sure to use inputs that are malicious like certain html entities. There are examples out there that give examples of malicious attacks (especially with sql injections and other such attacks) although I don't know how relevant they will be to an exporter used for tracing.
sdk/Trace/ExporterFactory.php
Outdated
public function fromConnectionString(string $configurationString) | ||
{ | ||
$strArr = explode('+', $configurationString); | ||
$contribName = $strArr[0]; |
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 agree with Aneurysm9, you must always sanitize any user input to protect from attacks. If we do have an allowed exporters list, then definitely use that as suggested.
/** | ||
* @test | ||
*/ | ||
public function testIfExporterHasCorrectEndpoint() |
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.
When writing you tests, make sure to use inputs that are malicious like certain html entities. There are examples out there that give examples of malicious attacks (especially with sql injections and other such attacks) although I don't know how relevant they will be to an exporter used for tracing.
$factory = new ExporterFactory('test.jaeger'); | ||
$exporter = $factory->fromConnectionString($input); | ||
$this->assertInstanceOf(Path\Jaeger\Exporter::class, $exporter); | ||
} |
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.
In terms of code structure these tests look good
sdk/Trace/ExporterFactory.php
Outdated
public function fromConnectionString(string $configurationString) | ||
{ | ||
$strArr = explode('+', $configurationString); | ||
$contribName = $strArr[0]; |
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.
Also look into the htmlentities() function which could serve as a way to sanitize input. Make sure it is relevant to your issue, usually it is used mostly to protect from front end malicious input.
…ort all exporters added
Some of the generator functions seem redundant. I still wrote them in case of future changes in the implementation of the 6 different Exporters. |
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.
Everything else seems really good with good code coverage. Just the htmlentities mistake I told you about
sdk/Trace/ExporterFactory.php
Outdated
*/ | ||
public function fromConnectionString(string $configurationString) | ||
{ | ||
$strArr = htmlentities($configurationString); |
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.
Ok so I made a mistake here, we should never escape input, its bad practice because it permanently ties that string to its final output format. So from what I understand you are usually only expecting some type of identifier with a url at the end. So what you want to do is filter the input to only be in the format you expect. Look at these filters here and here. You can also make your own filter through a regular expression which might be what you want. This will make sure that you are getting input only in the format that you desire.
From what I see, I don't believe these input values ever are on some type of html page so you can exclude the use of html entities. If it actually does end up on an html page you would use htmlentities() when your outputting it, not on input. So I think you can safely exclude htmlentities() since its just a url but definitely add the format filter you want instead
Used Nyholm Dsn parser for input string parsing. Modified unit tests and added testing for invalid licenseKey
sdk/Trace/ExporterFactory.php
Outdated
$licenseKey = ''; | ||
if ($endpointUrl != false) { | ||
$dsn = DsnParser::parse($endpointUrl); | ||
$endpointUrl = (string) ($dsn->withoutParameter('licenseKey')); | ||
$licenseKey = (string) ($dsn->getParameter('licenseKey')); | ||
} |
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 overly-specific. The handling of licenseKey
seems to only be applicable to the New Relic-flavored exporters. When new exporters are added that may have their own options this handling logic will need to change. Instead, if URL query string parameters are to be the mechanism for conveying configuration to exporters then they should be pulled into an array that is passed to the relevant constructor.
sdk/Trace/ExporterFactory.php
Outdated
return null; | ||
} | ||
|
||
// endpointUrl should only be null with otlp and otlpgrpc |
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.
If this is the case then it should be validated/enforced in some manner. Not really relevant to this PR, but out of curiosity how does the OTLP exporter get its target configuration? The exporter should definitely be able to be pointed at different destinations.
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 seems that otlp- is constructed with no args and gets its params fron env variables
Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
… into implement-exporterfactory
…11y/opentelemetry-php into implement-exporterfactory
sdk/Trace/ExporterFactory.php
Outdated
return $exporter; | ||
} | ||
|
||
private function _generateOtlp() |
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.
might this underscore have been forgotten to be removed?
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.
yes. thank you good catch
sdk/Trace/ExporterFactory.php
Outdated
return array_key_exists($exporter, $this->allowedExporters) && $this->allowedExporters[$exporter]; | ||
} | ||
|
||
// constructs the baseUrl from |
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.
(also another nit, but you may want to finish this comment)
Description
This PR addresses issue 184. With this update, the exporter can be selected via configuration string. The implementation was done by creating a factory class called ExporterFactory that takes in a string through env variable (config string) and creates the correct Exporter. Prior to this change, exporters needed to be injected to the processors manually as instances.
Currently this update only support Jaeger and Zipkin exporters.
Type of change
New feature
Testing
Implemented Unit test that ensure that the exporter is being chosen dynamically based on env variable.
Testing verified through
make test
Documentation
Documentation was added for the ExporterFactory file.