Re: [Freeipa-devel] [PATCH] 0119 Switch client to JSON-RPC

2013-11-26 Thread Petr Viktorin

On 11/26/2013 03:06 PM, Jan Cholasta wrote:

On 18.10.2013 12:26, Petr Viktorin wrote:

On 10/17/2013 06:08 PM, Jan Cholasta wrote:

Hi,

On 7.10.2013 18:16, Petr Viktorin wrote:

On 08/12/2013 10:17 AM, Petr Viktorin wrote:

On 08/02/2013 11:13 AM, Petr Viktorin wrote:

On 05/10/2013 04:54 PM, Petr Viktorin wrote:

On 04/01/2013 11:37 PM, Rob Crittenden wrote:

Petr Viktorin wrote:

On 01/15/2013 12:36 PM, Petr Viktorin wrote:

I meant to hold this patch a while longer to let it mature, but
from
what Brian Smith asked on the user list it seems it could help
him.

Design: http://freeipa.org/page/V3/JSON-RPC
Ticket: https://fedorahosted.org/freeipa/ticket/3299

See the design page for what the patch does.


As much as I've tried to avoid them, the code includes some
workarounds:
It extends xmlrpclib to also support JSON. This is rather
intrusive,
but
to not do that I'd need to write a parallel stack for JSON,
without
the
help of a standard library.


It would be nice to write the JSON stack in the future anyway, this
indeed seems intrusive to me.


Yes, it would.


The registration of either jsonclient or xmlclient as
rpcclient in
the
API also needs a bit of magic, since the framework requires the
class
name to match the attribute.


You could also put the name of the plugin in a configuration option and
address the plugin like api.Backend[api.env.rpcclient_plugin], but I
guess your solution is no worse.




To prevent backwards compatibility problems, we need to ensure
that
all
official JSON clients send the API version, so this patch
should be
applied after my patches 0104-0106.



Updating to current master.


Please reverse this change in ipalib/rpc.py:

@@ -665,8 +788,6 @@ class xmlclient(Connectible):
  except Exception, e:
  if not fallback:
  raise
-else:
-self.log.info('Connection to %s failed with
%s',
url, e)
  serverproxy = None

This logs connection errors when the client fails over to another
server.


Thanks. Done, and rebased to master.


Thanks for the patch, it works for me.

I have just a few nitpicks:

  def forward(self, *args, **kw):
  
-Forward call over XML-RPC to this same command on server.
+Forward call over JSON-RPC to this same command on server.

The new docstring is not entirely true.


Fixed, thanks


+def send_content(self, connection, request_body):
+if self.protocol == 'json':
+connection.putheader(Content-Type, application/json)
+else:
+connection.putheader(Content-Type, text/xml)
+
+connection.putheader(Content-Length, str(len(request_body)))
+connection.endheaders(request_body)

The original implementation of send_content in the Transport class sets
up gzip compression. I think it may be useful to do it here as well.


We don't opt in for gzip compression, so that's unnecessary.
I've added a comment.


+def rpc_uri_from_env(self, env):
+raise NotImplementedError('RPCClient.rpc_uri_from_env')
...
-xmlrpc_uri = self.env.xmlrpc_uri
+rpc_uri = self.rpc_uri_from_env(self.env)

I don't think this is necessary, since Env is also a mapping, you can do
this instead:

+env_rpc_uri_var = None
...
-xmlrpc_uri = self.env.xmlrpc_uri
+rpc_uri = self.env[env_rpc_uri_var]


You're right, changed


+class xmlclient(RPCClient):
+session_path = '/ipa/session/xml'
+server_proxy_class = ServerProxy
+protocol = 'xml'
+wrap_functions = xml_wrap, xml_unwrap
...
+class jsonclient(RPCClient):
+session_path = '/ipa/session/json'
+server_proxy_class = JSONServerProxy
+protocol = 'json'
+wrap_functions = identity, identity

It seems to me that json_encode_binary and json_decode_binary are
equivallent to xml_wrap and xml_unwrap, is there a reason you used the
identity function in jsonclient.wrap_functions?


Yes, it's for unwrapping error results. For JSON, we want the decoding
done before the error is raised, but for XML no decoding is done (error
results can't contain binary data).
I've moved this into a single method, hopefully it's clearer this way.



Thanks. ACK once you remove the unused identity function.


Thank you!
Removed the function and pushed to master: 
73b8047b2298d347475a5c8d9f1853052ddced57





--
Petr³

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH] 0119 Switch client to JSON-RPC

2013-10-17 Thread Jan Cholasta

Hi,

On 7.10.2013 18:16, Petr Viktorin wrote:

On 08/12/2013 10:17 AM, Petr Viktorin wrote:

On 08/02/2013 11:13 AM, Petr Viktorin wrote:

On 05/10/2013 04:54 PM, Petr Viktorin wrote:

On 04/01/2013 11:37 PM, Rob Crittenden wrote:

Petr Viktorin wrote:

On 01/15/2013 12:36 PM, Petr Viktorin wrote:

I meant to hold this patch a while longer to let it mature, but from
what Brian Smith asked on the user list it seems it could help him.

Design: http://freeipa.org/page/V3/JSON-RPC
Ticket: https://fedorahosted.org/freeipa/ticket/3299

See the design page for what the patch does.


As much as I've tried to avoid them, the code includes some
workarounds:
It extends xmlrpclib to also support JSON. This is rather intrusive,
but
to not do that I'd need to write a parallel stack for JSON, without
the
help of a standard library.


It would be nice to write the JSON stack in the future anyway, this 
indeed seems intrusive to me.



The registration of either jsonclient or xmlclient as rpcclient in
the
API also needs a bit of magic, since the framework requires the
class
name to match the attribute.


You could also put the name of the plugin in a configuration option and 
address the plugin like api.Backend[api.env.rpcclient_plugin], but I 
guess your solution is no worse.





To prevent backwards compatibility problems, we need to ensure that
all
official JSON clients send the API version, so this patch should be
applied after my patches 0104-0106.



Updating to current master.


Please reverse this change in ipalib/rpc.py:

@@ -665,8 +788,6 @@ class xmlclient(Connectible):
  except Exception, e:
  if not fallback:
  raise
-else:
-self.log.info('Connection to %s failed with %s',
url, e)
  serverproxy = None

This logs connection errors when the client fails over to another
server.


Thanks. Done, and rebased to master.


Thanks for the patch, it works for me.

I have just a few nitpicks:

 def forward(self, *args, **kw):
 
-Forward call over XML-RPC to this same command on server.
+Forward call over JSON-RPC to this same command on server.

The new docstring is not entirely true.


+def send_content(self, connection, request_body):
+if self.protocol == 'json':
+connection.putheader(Content-Type, application/json)
+else:
+connection.putheader(Content-Type, text/xml)
+
+connection.putheader(Content-Length, str(len(request_body)))
+connection.endheaders(request_body)

The original implementation of send_content in the Transport class sets 
up gzip compression. I think it may be useful to do it here as well.



+def rpc_uri_from_env(self, env):
+raise NotImplementedError('RPCClient.rpc_uri_from_env')
...
-xmlrpc_uri = self.env.xmlrpc_uri
+rpc_uri = self.rpc_uri_from_env(self.env)

I don't think this is necessary, since Env is also a mapping, you can do 
this instead:


+env_rpc_uri_var = None
...
-xmlrpc_uri = self.env.xmlrpc_uri
+rpc_uri = self.env[env_rpc_uri_var]


+class xmlclient(RPCClient):
+session_path = '/ipa/session/xml'
+server_proxy_class = ServerProxy
+protocol = 'xml'
+wrap_functions = xml_wrap, xml_unwrap
...
+class jsonclient(RPCClient):
+session_path = '/ipa/session/json'
+server_proxy_class = JSONServerProxy
+protocol = 'json'
+wrap_functions = identity, identity

It seems to me that json_encode_binary and json_decode_binary are 
equivallent to xml_wrap and xml_unwrap, is there a reason you used the 
identity function in jsonclient.wrap_functions?





The changes look really good. The show stopper is that using jsonrpc
doesn't create a session key. I noticed that xmlrpc_uri is hardcoded
into ipalib/session.py but it appears the issue is deeper than that.


That uses only the hostname from xmlrpc_uri. When using different
hostnames in xmlrpc_uri and jsonrpc_uri *on the server*, it'll put the
wrong domain in the cookie. In this case I think it's the configuration
that's wrong.

The real problem is that KerberossSession code which creates the
cookie,
was not called by the JSON server.
Patch 0223 adds it.


ACK.



Patch 0224 adds the server class name (e.g. [jsonserver_kerb]) to the
server logs. It should help debug problems specific to a
backend/protocol.


ACK.



Rebased onto current master.



Another minor rebase



Rebased again.



Honza

--
Jan Cholasta

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH] 0119 Switch client to JSON-RPC

2013-04-01 Thread Rob Crittenden

Petr Viktorin wrote:

On 01/15/2013 12:36 PM, Petr Viktorin wrote:

I meant to hold this patch a while longer to let it mature, but from
what Brian Smith asked on the user list it seems it could help him.

Design: http://freeipa.org/page/V3/JSON-RPC
Ticket: https://fedorahosted.org/freeipa/ticket/3299

See the design page for what the patch does.


As much as I've tried to avoid them, the code includes some workarounds:
It extends xmlrpclib to also support JSON. This is rather intrusive, but
to not do that I'd need to write a parallel stack for JSON, without the
help of a standard library.
The registration of either jsonclient or xmlclient as rpcclient in the
API also needs a bit of magic, since the framework requires the class
name to match the attribute.


To prevent backwards compatibility problems, we need to ensure that all
official JSON clients send the API version, so this patch should be
applied after my patches 0104-0106.



Updating to current master.


Please reverse this change in ipalib/rpc.py:

@@ -665,8 +788,6 @@ class xmlclient(Connectible):
 except Exception, e:
 if not fallback:
 raise
-else:
-self.log.info('Connection to %s failed with %s', 
url, e)

 serverproxy = None

This logs connection errors when the client fails over to another server.

The changes look really good. The show stopper is that using jsonrpc 
doesn't create a session key. I noticed that xmlrpc_uri is hardcoded 
into ipalib/session.py but it appears the issue is deeper than that.


I did some basic testing with an old client against this server and 
things seem to be fine.


I get the same results running the unit tests with both rpclib settings.

rob

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH] 0119 Switch client to JSON-RPC

2013-02-14 Thread Petr Viktorin

On 01/15/2013 12:36 PM, Petr Viktorin wrote:

I meant to hold this patch a while longer to let it mature, but from
what Brian Smith asked on the user list it seems it could help him.

Design: http://freeipa.org/page/V3/JSON-RPC
Ticket: https://fedorahosted.org/freeipa/ticket/3299

See the design page for what the patch does.


As much as I've tried to avoid them, the code includes some workarounds:
It extends xmlrpclib to also support JSON. This is rather intrusive, but
to not do that I'd need to write a parallel stack for JSON, without the
help of a standard library.
The registration of either jsonclient or xmlclient as rpcclient in the
API also needs a bit of magic, since the framework requires the class
name to match the attribute.


To prevent backwards compatibility problems, we need to ensure that all
official JSON clients send the API version, so this patch should be
applied after my patches 0104-0106.



Updating to current master.


--
Petr³
From 87bade151fd8865c29a16d817c841074754a0d26 Mon Sep 17 00:00:00 2001
From: Petr Viktorin pvikt...@redhat.com
Date: Wed, 19 Dec 2012 04:25:24 -0500
Subject: [PATCH] Switch client to JSON-RPC

Modify ipalib.rpc to support JSON-RPC in addition to XML-RPC.
This is done by subclassing and extending xmlrpclib, because
our existing code relies on xmlrpclib internals.

The URI to use is given in the new jsonrpc_uri env variable. When
it is not given, it is generated from xmlrpc_uri by replacing
/xml with /json.

The rpc_json_uri env variable existed before, but was unused,
undocumented and not set the install scripts.
This patch removes it in favor of jsonrpc_uri (for consistency
with xmlrpc_uri).

Add the rpc_protocol env variable to control the protocol
IPA uses. rpc_protocol defaults to 'jsonrpc', but may be changed
to 'xmlrpc'.
Make backend.Executioner and tests use the backend specified by
rpc_protocol.

For compatibility with unwrap_xml, decoding JSON now gives tuples
instead of lists.

Design: http://freeipa.org/page/V3/JSON-RPC
Ticket: https://fedorahosted.org/freeipa/ticket/3299
---
 ipa-client/man/default.conf.5 |8 +-
 ipalib/backend.py |2 +-
 ipalib/config.py  |   21 ++-
 ipalib/constants.py   |7 +-
 ipalib/frontend.py|4 +-
 ipalib/plugins/{xmlclient.py = rpcclient.py} |   24 ++-
 ipalib/rpc.py |  271 +
 ipaserver/rpcserver.py|  113 +-
 tests/test_cmdline/test_cli.py|4 +-
 tests/test_ipaserver/test_rpcserver.py|4 +-
 tests/test_xmlrpc/test_dns_plugin.py  |4 +-
 tests/test_xmlrpc/test_trust_plugin.py|4 +-
 tests/test_xmlrpc/xmlrpc_test.py  |8 +-
 13 files changed, 312 insertions(+), 162 deletions(-)
 rename ipalib/plugins/{xmlclient.py = rpcclient.py} (58%)

diff --git a/ipa-client/man/default.conf.5 b/ipa-client/man/default.conf.5
index a0804e39f946b3202acc32cc6a7ccbdb8f2626e6..edaa16ee15cdf74caa19910854e5abcabbd525de 100644
--- a/ipa-client/man/default.conf.5
+++ b/ipa-client/man/default.conf.5
@@ -179,7 +179,13 @@ Used internally in the IPA source package to verify that the API has not changed
 When True provides more information. Specifically this sets the global log level to info.
 .TP
 .B xmlrpc_uri URI
-Specifies the URI of the XML\-RPC server for a client. This is used by IPA and some external tools as well, such as ipa\-getcert. e.g. https://ipa.example.com/ipa/xml
+Specifies the URI of the XML\-RPC server for a client. This may be used by IPA, and is used by some external tools, such as ipa\-getcert. Example: https://ipa.example.com/ipa/xml
+.TP
+.B jsonrpc_uri URI
+Specifies the URI of the JSON server for a client. This is used by IPA. If not given, it is derived from xmlrpc_uri. Example: https://ipa.example.com/ipa/json
+.TP
+.B rpc_protocol URI
+Specifies the type of RPC calls IPA makes: 'jsonrpc' or 'xmlrpc'. Defaults to 'jsonrpc'.
 .TP
 The following define the containers for the IPA server. Containers define where in the DIT that objects can be found. The full location is the value of container + basedn.
   container_accounts: cn=accounts
diff --git a/ipalib/backend.py b/ipalib/backend.py
index 7be38ecc80faf03e735813fb1e2d0eba5c347800..b94264236795b65905ba425ef15e452e7a66625b 100644
--- a/ipalib/backend.py
+++ b/ipalib/backend.py
@@ -113,7 +113,7 @@ class Executioner(Backend):
 if self.env.in_server:
 self.Backend.ldap2.connect(ccache=ccache)
 else:
-self.Backend.xmlclient.connect(verbose=(self.env.verbose = 2),
+self.Backend.rpcclient.connect(verbose=(self.env.verbose = 2),
 fallback=self.env.fallback, delegate=self.env.delegate)
 if client_ip is not None:
 setattr(context, client_ip, client_ip)
diff --git a/ipalib/config.py b/ipalib/config.py
index 

[Freeipa-devel] [PATCH] 0119 Switch client to JSON-RPC

2013-01-15 Thread Petr Viktorin
I meant to hold this patch a while longer to let it mature, but from 
what Brian Smith asked on the user list it seems it could help him.


Design: http://freeipa.org/page/V3/JSON-RPC
Ticket: https://fedorahosted.org/freeipa/ticket/3299

See the design page for what the patch does.


As much as I've tried to avoid them, the code includes some workarounds:
It extends xmlrpclib to also support JSON. This is rather intrusive, but 
to not do that I'd need to write a parallel stack for JSON, without the 
help of a standard library.
The registration of either jsonclient or xmlclient as rpcclient in the 
API also needs a bit of magic, since the framework requires the class 
name to match the attribute.



To prevent backwards compatibility problems, we need to ensure that all 
official JSON clients send the API version, so this patch should be 
applied after my patches 0104-0106.


--
Petr³
From 14400d8561560fc4dac7cd026d3ae5e8832c97f8 Mon Sep 17 00:00:00 2001
From: Petr Viktorin pvikt...@redhat.com
Date: Wed, 19 Dec 2012 04:25:24 -0500
Subject: [PATCH] Switch client to JSON-RPC

Modify ipalib.rpc to support JSON-RPC in addition to XML-RPC.
This is done by subclassing and extending xmlrpclib, because
our existing code relies on xmlrpclib internals.

The URI to use is given in the new jsonrpc_uri env variable. When
it is not given, it is generated from xmlrpc_uri by replacing
/xml with /json.

The rpc_json_uri env variable existed before, but was unused,
undocumented and not set the install scripts.
This patch removes it in favor of jsonrpc_uri (for consistency
with xmlrpc_uri).

Add the rpc_protocol env variable to control the protocol
IPA uses. rpc_protocol defaults to 'jsonrpc', but may be changed
to 'xmlrpc'.
Make backend.Executioner and tests use the backend specified by
rpc_protocol.

For compatibility with unwrap_xml, decoding JSON now gives tuples
instead of lists.

Design: http://freeipa.org/page/V3/JSON-RPC
Ticket: https://fedorahosted.org/freeipa/ticket/3299
---
 ipa-client/man/default.conf.5 |8 +-
 ipalib/backend.py |2 +-
 ipalib/config.py  |   21 ++-
 ipalib/constants.py   |7 +-
 ipalib/frontend.py|4 +-
 ipalib/plugins/{xmlclient.py = rpcclient.py} |   24 ++-
 ipalib/rpc.py |  271 +
 ipaserver/rpcserver.py|  113 +-
 tests/test_cmdline/test_cli.py|4 +-
 tests/test_ipaserver/test_rpcserver.py|4 +-
 tests/test_xmlrpc/test_dns_plugin.py  |4 +-
 tests/test_xmlrpc/xmlrpc_test.py  |8 +-
 12 files changed, 310 insertions(+), 160 deletions(-)
 rename ipalib/plugins/{xmlclient.py = rpcclient.py} (58%)

diff --git a/ipa-client/man/default.conf.5 b/ipa-client/man/default.conf.5
index a0804e39f946b3202acc32cc6a7ccbdb8f2626e6..edaa16ee15cdf74caa19910854e5abcabbd525de 100644
--- a/ipa-client/man/default.conf.5
+++ b/ipa-client/man/default.conf.5
@@ -179,7 +179,13 @@ Used internally in the IPA source package to verify that the API has not changed
 When True provides more information. Specifically this sets the global log level to info.
 .TP
 .B xmlrpc_uri URI
-Specifies the URI of the XML\-RPC server for a client. This is used by IPA and some external tools as well, such as ipa\-getcert. e.g. https://ipa.example.com/ipa/xml
+Specifies the URI of the XML\-RPC server for a client. This may be used by IPA, and is used by some external tools, such as ipa\-getcert. Example: https://ipa.example.com/ipa/xml
+.TP
+.B jsonrpc_uri URI
+Specifies the URI of the JSON server for a client. This is used by IPA. If not given, it is derived from xmlrpc_uri. Example: https://ipa.example.com/ipa/json
+.TP
+.B rpc_protocol URI
+Specifies the type of RPC calls IPA makes: 'jsonrpc' or 'xmlrpc'. Defaults to 'jsonrpc'.
 .TP
 The following define the containers for the IPA server. Containers define where in the DIT that objects can be found. The full location is the value of container + basedn.
   container_accounts: cn=accounts
diff --git a/ipalib/backend.py b/ipalib/backend.py
index 7be38ecc80faf03e735813fb1e2d0eba5c347800..b94264236795b65905ba425ef15e452e7a66625b 100644
--- a/ipalib/backend.py
+++ b/ipalib/backend.py
@@ -113,7 +113,7 @@ class Executioner(Backend):
 if self.env.in_server:
 self.Backend.ldap2.connect(ccache=ccache)
 else:
-self.Backend.xmlclient.connect(verbose=(self.env.verbose = 2),
+self.Backend.rpcclient.connect(verbose=(self.env.verbose = 2),
 fallback=self.env.fallback, delegate=self.env.delegate)
 if client_ip is not None:
 setattr(context, client_ip, client_ip)
diff --git a/ipalib/config.py b/ipalib/config.py
index 3c9aeaa2880cb67c7f230ecba4839d37e77b04f2..f86c0a5ea3885d2bf89712f91b0c0705dceedd32 100644
--- a/ipalib/config.py
+++