Skip to content

New pips, second try - #18

Open
msalle wants to merge 16 commits into
argus-authz:1_7from
msalle:new_pips_v2
Open

New pips, second try#18
msalle wants to merge 16 commits into
argus-authz:1_7from
msalle:new_pips_v2

Conversation

@msalle

@msalle msalle commented Jan 12, 2017

Copy link
Copy Markdown
Member

Hi Andrea,
hereby a new pull request.

Adding X509ExtractorPIP and PolicyNamesPIP with corresponding
*IniConfigurationParser classes and *Test classes.
PolicyNamesPIP makes use of a sub package policynamespip for a caching the info
files.
This solves argus-authz#15.
Add new PIPs including default config to pepd.ini
junit framework is deprecated in favour of junit tests indicated with @test etc.
This requires a newer version of junit.
Add two new policy files which combine the standard IGTF policies, in order to
simplify Argus PAP policy matching: WLCG VOs can be matched using
policy-aspen-birch-cedar-dogwood while other VOs need to combine with
policy-aspen-birch-cedar.
Before trying to get the modification time, test whether the file actually
exists.
Introduce intermediate class UpdatingPolicyNamesCache that takes care of the
updating of the PolicyNamesCache (formerly PolicyNamesPIPCache).
The PIP itself now does not need to keep track of that. Remove the unused and
non-trivial possibility of updating the trust dir for a running PIP.
Implement proper read/write locks to prevent memory corruption.
@msalle msalle mentioned this pull request Jan 12, 2017

@andreaceccanti andreaceccanti left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Mischa,
I've reviewed the code more deeply (see comments).

In general things look good, but there are things that should be fixed to align it better to Java recommendations for code and other stuff.

The main comment about the updatingCache is about delegating the update responsibility to a background thread. If you don't want to implement that I can do it.

Thanks!

Comment thread src/main/assembly/fakeroot.xml Outdated
<!-- .info files -->
<fileSet>
<directory>src/main/infofiles</directory>
<outputDirectory>/etc/grid-security/certificates</outputDirectory>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like very much the idea that the info files end up in /etc/grid-security/certificates, and that
Argus owns stuff in that directory.

Are these files argus specific? If so, they could live in /etc/argus. If not, they shouldn't be packaged in Argus.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are indeed Argus specific, in that they don't (and will not) come from IGTF, but they do have the status of policy .info files in the same way as the policy-igtf-classic.info. Having them in /etc/argus will not work therefore, since they would not be found. The reason for having them in the first place, is to prevent us from needing separate permit lines for each individual policy (e.g. classic, mics, slcs and iota) but instead making a single entry with e.g. policy-aspen-birch-cedar-dogwood.
What we could do is put the file itself in /etc/argus/... and make a symlink into the /etc/grid-security/certificates directory.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since these files are fully argus-specific, then it's up to the PIP to look them up in whatever directory we choose, or am I missing something? I would go for something into /etc/argus/, but also /etc/grid-security/argus/ would be fine for me (following an approach similar to /etc/grid-security/vomsdir).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've discussed with DavidG and we could try to push them via the EGI policy packages (such as ca-policy-egi-core-1.79-1.noarch.rpm), which are specific to EGI, and actually also produced by David with an EGI hat instead of IGTF hat. The point is that the PIP looks in the 'trustDir' (i.e. normally /etc/grid-security/certificates) for all the info files, and hence that's also where these files should end up, either as file or as symlink. Any other directory does not make sense since they are the same sort of file from the PIP perspective. They are (reasonably) normal info files, only not IGTF.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point is that the PIP looks in the 'trustDir' (i.e. normally /etc/grid-security/certificates) for all the info file

The point is: are these files meant to be used by other services? If not, they should be packaged in an argus-owned directory, and the PIP modified to look into this directory.
I think the fact that the policy files and certificates must live in the same dir is only a limitation of the current PIP policy lookup implementation, or there's more to it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, they might be used by other services, in that sense they're not specific to Argus, hence the suggestion to ship them with the EGI policy packages. For most services they are probably not needed, Argus needs them due to the limitation that we can not make logical OR statements in a permit rule, something along the lines of

rule permit {
      vo="atlas"
      { ca-policy-names="policy-igtf-classic" OR
        ca-policy-names="policy-igtf-mics" OR
        ca-policy-names="policy-igtf-slcs" OR
        ca-policy-names="policy-igtf-iota"
      }
  }

Furthermore, info files have always been in the same directory as the pem files, that includes policy info files such as policy-igtf-classic.info but also the info files for the CAs themselves.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so it seems we have an agreement that these files should be packaged outside of the Argus PEPD, in a different package, provided by EGI, so please remove them from the assembly file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. Same thing for the src/main/assembly/standalone.xml

throws PIPProcessingException
{
long t0=System.nanoTime();
boolean pipprocessed=false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java favours camelCase, so this should be pipProcessed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
long t0=System.nanoTime();
boolean pipprocessed=false;
String issuerdn=null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issuerdn -> issuerDn

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

for (Attribute attr: attributes) {
if (ATTR_X509_ISSUER.equals(attr.getId())) {
// Take first value (it should be singlevalued)
Object tmp = attr.getValues().iterator().next();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tmp is a bad name, probably x509IssuerAttr is a better alternative

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

// Look for the issuerdn in the .info files
String[] policynames=new String[0];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

policynames -> policyNames

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

read.lock();
try {
// Protect against empty cache
if (cache == null) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there really a case when the cache can be null?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not, perhaps this should be an assertion instead, but in any case I don't like NPEs...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you don't like NPEs, you should use an Optional for the cache.
I would drop this, since there's really no chance, if the code is written properly, that the cache is null.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// First check (with appropriate read lock) whether we need to do
// anything. If so, create a new cache.
read.lock();
try {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would drop this in favour of a separate thread that just takes the write lock according to a specified period

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the separate thread, but the write lock would also block use of the old cache which is still valid... It's not really an issue, since updating the set won't take that long, but still...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That wouldn't be a problem

// out-of-date (i.e. hasn't been updated in the mean time by another
// thread
if (newCache==null)
// This probably never happens: exception will have been thrown

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should drop the code if it never happens

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably never happens, but as C programmer I really don't like NPEs.

// This probably never happens: exception will have been thrown
log.warn("New cache is null, continuing to use old one");
else if (cache.getLifeTime() < update_interval)
log.info("Other thread appears to have already updated cache");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can also go away if you use the background updater thread

String message= e.getMessage();
log.debug("EXPECTED: " + message);
log.debug("GOT ("+message.indexOf(element)+"): " + element);
assertTrue("PIPProcessingException message does not contain: " + element, message.indexOf(element) >= 0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of these general assertTrue/assertFalse, which produce ugly output difficoult to understand, people use the hamcrest matchers library and the assertThat method, which makes the test and output more readable

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could I ask you to rewrite those? I've mostly copied from how things are currently done in the other PIPs. I agree fully that it's ugly, but then we should change it in all.

@andreaceccanti andreaceccanti Jan 17, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we should have consistency, but my objective here is to ensure that new code that enters to the codebase satisfies certain requirements. So please try the migration to hamcrest, and if you have questions/doubts I will be happy to help

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've replaced it in a way similar to https://github.com/italiangrid/voms-api-java/blob/master/src/test/java/org/italiangrid/voms/test/TestVOMSESLineParser.java#L70-L73
so using assertThat with a CoreMatcher. I had to update the junit dependency to 4.11 to get it working.
Is this what you had in mind?

Fixing comments from argus-authz#18
- camelCase
- use slf4j placeholders
- use String.format()
- use {} in all blocks
- rethrow exceptions (in certain cases)
- log some exceptions before throwing them.
- use TimeUnit to convert hours to millisecs
- rename some vars for clarity
Fixed one more block missing braces
Make Logger for each PIP private static final.
Use assertThat and a hamcrest matcher instead of a not so readable assertTrue
for testing the message of a exception. assertThat needs a slightly newer junit.
The two meta policy info files policy-aspen-birch-cedar-dogwood.info and
policy-aspen-birch-cedar.info will be packaged in an external package.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants