@@ -32,6 +32,101 @@ def self.unversioned_internal_auth_url(node, admin_host)
3232 service_URL ( node [ :keystone ] [ :api ] [ :protocol ] , admin_host , node [ :keystone ] [ :api ] [ :service_port ] )
3333 end
3434
35+ # NOTE(gyee): trusted_dashboard in Keystone can be multiple URLs.
36+ # For example, in a typical production deployment, there can be multiple
37+ # Horizon endpoints, depending on where Horizon is being accessed. For
38+ # example, the endpoint for access inside the firewall could be different
39+ # from the one that is outside of the firewall. And in some cases, the
40+ # endpoint could be the corporate HTTP proxy.
41+ # For now, we are prepopulating one that is only understood by Crowbar for
42+ # testing/demo purpopses. In a production environment, it can be amended with
43+ # other external endpoints.
44+ def self . dashboard_public_url ( dashboard_node )
45+ ha_enabled = dashboard_node [ :horizon ] [ :ha ] [ :enabled ]
46+ ssl_enabled = dashboard_node [ :horizon ] [ :apache ] [ :ssl ]
47+ want_fqdn = true
48+ public_fqdn = CrowbarHelper . get_host_for_public_url (
49+ dashboard_node ,
50+ ssl_enabled ,
51+ ha_enabled ,
52+ want_fqdn
53+ )
54+
55+ protocol = "http"
56+ protocol = "https" if ssl_enabled
57+
58+ "#{ protocol } ://#{ public_fqdn } "
59+ end
60+
61+ def self . websso_enabled ( node )
62+ node [ :keystone ] [ :federation ] [ :openidc ] [ :enabled ]
63+ end
64+
65+ def self . trusted_dashboard_url ( node )
66+ # NOTE(gyee): since Horizon is depended on Keystone and will be deployed
67+ # after Keystone, the Horizon node may not be available when Keystone
68+ # is first deployed. However, chef executes the recipes periodically.
69+ # On the next chef run after, after Horizon had deployed, we should be
70+ # able to figure out the trusted_dashboard from the node, assuming Horizon
71+ # is always deployed on the same node as Keystone. Otherwise, we'll need
72+ # to do node search.
73+
74+ horizon_server = CrowbarUtilsSearch . node_search_with_cache ( node , "roles:horizon-server" ) . first
75+
76+ unless horizon_server . nil?
77+ horizon_url =
78+ if horizon_server [ "horizon" ] . key? ( "apache" )
79+ ::File . join ( dashboard_public_url ( horizon_server ) , "/auth/websso/" )
80+ else
81+ ""
82+ end
83+ end
84+
85+ horizon_url
86+ end
87+
88+ def self . trusted_dashboards ( node )
89+ # NOTE(gyee): if user does not specify any trusted_dashboards, we'll
90+ # automagically generate one based on the current knowned crowbar
91+ # configuration.
92+ if node [ :keystone ] [ :federation ] [ :trusted_dashboards ] . empty?
93+ node [ :keystone ] [ :federation ] [ :trusted_dashboards ] << trusted_dashboard_url ( node )
94+ end
95+
96+ node [ :keystone ] [ :federation ] [ :trusted_dashboards ]
97+ end
98+
99+ # NOTE(gyee): for some WebSSO protocols (i.e. saml, openidc, etc), the
100+ # authentication process involves redirecting the browser to the identity
101+ # provider's endpoint for authentication, then the user is redirected back
102+ # to Keystone upon successfully authentication with the identity provider.
103+ # Therefore, the Keystone redirect URL must be external or public as it needs
104+ # to be accessible by the browsers. Also, in some cases, the URL needs to be
105+ # fully qualified. For example, Google OpenID Connection requires the URL to
106+ # be FQDN instead of IP as it must match the authorized domain. Therefore,
107+ # the WEBSSO_KEYSTONE_URL in Horizon should contain the FQDN, depending
108+ # on the identity provider. For production deployments, we offers the user
109+ # the ability to override it because we don't know the user's network
110+ # topology beforehand. For example, the external endpoint could be handled
111+ # by an HTTP proxy which may not be known to crowbar.
112+ def self . websso_keystone_url ( node )
113+ ha_enabled = node [ :keystone ] [ :ha ] [ :enabled ]
114+ ssl_enabled = node [ "keystone" ] [ "api" ] [ "protocol" ] == "https"
115+ want_fqdn = true
116+ public_fqdn = CrowbarHelper . get_host_for_public_url ( node , ssl_enabled , ha_enabled , want_fqdn )
117+
118+ websso_keystone_url =
119+ if node [ :keystone ] [ :federation ] [ :websso_keystone_url ] . empty?
120+ # Will use the one automagically generated by crowbar if user doesn't
121+ # explicitly set one. This should be for testing/demo purposes in most
122+ # cases.
123+ public_auth_url ( node , public_fqdn )
124+ else
125+ node [ :keystone ] [ :federation ] [ :websso_keystone_url ]
126+ end
127+ websso_keystone_url
128+ end
129+
35130 def self . keystone_settings ( current_node , cookbook_name )
36131 instance = current_node [ cookbook_name ] [ :keystone_instance ] || "default"
37132
@@ -56,7 +151,6 @@ def self.keystone_settings(current_node, cookbook_name)
56151 ha_enabled = node [ :keystone ] [ :ha ] [ :enabled ]
57152 use_ssl = node [ "keystone" ] [ "api" ] [ "protocol" ] == "https"
58153 public_host = CrowbarHelper . get_host_for_public_url ( node , use_ssl , ha_enabled )
59-
60154 admin_host = CrowbarHelper . get_host_for_admin_url ( node , ha_enabled )
61155
62156 has_default_user = node [ "keystone" ] [ "default" ] [ "create_user" ]
@@ -71,6 +165,7 @@ def self.keystone_settings(current_node, cookbook_name)
71165 "api_version_for_middleware" => "v%.1f" % node [ :keystone ] [ :api ] [ :version ] ,
72166 "admin_auth_url" => admin_auth_url ( node , admin_host ) ,
73167 "public_auth_url" => public_auth_url ( node , public_host ) ,
168+ "websso_keystone_url" => websso_keystone_url ( node ) ,
74169 "internal_auth_url" => internal_auth_url ( node , admin_host ) ,
75170 "unversioned_internal_auth_url" => unversioned_internal_auth_url ( node , admin_host ) ,
76171 "use_ssl" => use_ssl ,
@@ -95,7 +190,9 @@ def self.keystone_settings(current_node, cookbook_name)
95190 "default_user_domain_id" => has_default_user ? default_domain_id : nil ,
96191 "default_password" => has_default_user ? node [ "keystone" ] [ "default" ] [ "password" ] : nil ,
97192 "service_project" => node [ "keystone" ] [ "service" ] [ "project" ] ,
98- "service_tenant" => node [ "keystone" ] [ "service" ] [ "project" ]
193+ "service_tenant" => node [ "keystone" ] [ "service" ] [ "project" ] ,
194+ "websso_enabled" => websso_enabled ( node ) ,
195+ "trusted_dashboards" => trusted_dashboards ( node )
99196 }
100197 end
101198
0 commit comments