Browse files

Parent role should not be blocked in disable_instance

  1. Default user (Parent role) should not be blocked for it will be used in dump_instance
  2. Unit test update: kill long transaction should only work for normal user rather than default user and super user

Change-Id: I032ac9060eef24f476d9d947c550ee952b0ca1a8
  • Loading branch information...
1 parent c5e63e1 commit f202332a00d628059734cd4d9ba13233af663294 @mflu mflu committed Apr 1, 2012
View
2 postgresql/config/postgresql_node.yml
@@ -7,7 +7,7 @@ ip_route: 127.0.0.1
restore_bin: pg_restore
dump_bin: pg_dump
mbus: nats://localhost:4222
-index : 0
+index: 0
logging:
level: debug
pid: /var/vcap/sys/run/postgresql_node.pid
View
28 postgresql/lib/postgresql_service/node.rb
@@ -625,17 +625,25 @@ def get_postgres_version(db_connection)
def block_user_from_db(db_connection, service)
name = service.name
+ default_user = service.bindusers.all(:default_user => true)[0]
service.bindusers.all.each do |binduser|
- db_connection.query("revoke connect on database #{name} from #{binduser.user}")
- db_connection.query("revoke connect on database #{name} from #{binduser.sys_user}")
+ if binduser.default_user == false
+ db_connection.query("revoke #{default_user.user} from #{binduser.user}")
+ db_connection.query("revoke connect on database #{name} from #{binduser.user}")
+ db_connection.query("revoke connect on database #{name} from #{binduser.sys_user}")
+ end
end
end
def unblock_user_from_db(db_connection, service)
name = service.name
+ default_user = service.bindusers.all(:default_user => true)[0]
service.bindusers.all.each do |binduser|
- db_connection.query("GRANT CONNECT ON DATABASE #{name} to #{binduser.user}")
- db_connection.query("GRANT CONNECT ON DATABASE #{name} to #{binduser.sys_user}")
+ if binduser.default_user == false
+ db_connection.query("GRANT CONNECT ON DATABASE #{name} to #{binduser.user}")
+ db_connection.query("GRANT CONNECT ON DATABASE #{name} to #{binduser.sys_user}")
+ db_connection.query("GRANT #{default_user.user} to #{binduser.user}")
+ end
end
end
@@ -658,17 +666,7 @@ def restore(name, backup_path)
raise PostgresqlError.new(PostgresqlError::POSTGRESQL_CONFIG_NOT_FOUND, name) unless service
default_user = service.bindusers.all(:default_user => true)[0]
raise "No default user for provisioned service #{name}" unless default_user
-
- db_connection = postgresql_connect(@postgresql_config["host"], @postgresql_config["user"], @postgresql_config["pass"], @postgresql_config["port"], name)
- block_user_from_db(db_connection, service)
- db_connection.close
- exe_drop_database(name)
- exe_create_database(name)
-
- db_connection = postgresql_connect(@postgresql_config["host"], @postgresql_config["user"], @postgresql_config["pass"], @postgresql_config["port"], name)
- exe_grant_user_priv(db_connection)
- unblock_user_from_db(db_connection, service)
- db_connection.close
+ reset_db(@postgresql_config['host'], @postgresql_config['port'], @postgresql_config['user'], @postgresql_config['pass'], name, service)
host, port = %w{host port}.map { |opt| @postgresql_config[opt] }
path = File.join(backup_path, "#{name}.dump")
View
60 postgresql/spec/postgresql_node_spec.rb
@@ -97,10 +97,10 @@ class PostgresqlError
conn2 = connect_to_postgresql(bind_cred)
@test_dbs[@db] << bind_cred
@node.disable_instance(@db, [bind_cred])
- expect { conn.query('select 1') }.should raise_error
- expect { conn2.query('select 1') }.should raise_error
- expect { connect_to_postgresql(@db) }.should raise_error
- expect { connect_to_postgresql(bind_cred) }.should raise_error
+ expect { conn.query('select 1') }.should raise_error # expected exception: connection terminated
+ expect { conn2.query('select 1') }.should raise_error # expected exception: connection terminated
+ expect { connect_to_postgresql(@db) }.should_not raise_error # default user won't be blocked
+ expect { connect_to_postgresql(bind_cred) }.should raise_error #expected exception: no permission to connect
EM.stop
end
end
@@ -135,8 +135,8 @@ class PostgresqlError
@test_dbs[db] << binding
conn = connect_to_postgresql(binding)
@node.disable_instance(db, [binding])
- expect {conn = connect_to_postgresql(binding)}.should raise_error
- expect {conn = connect_to_postgresql(db)}.should raise_error
+ expect {conn = connect_to_postgresql(binding)}.should raise_error # expected exception: no permission to connect
+ expect {conn = connect_to_postgresql(db)}.should_not raise_error
value = {
"fake_service_id" => {
"credentials" => binding,
@@ -316,21 +316,59 @@ class PostgresqlError
db = node.provision('free')
binding = node.bind(db['name'], @default_opts)
@test_dbs[db] = [binding]
- # use a non-default user (not parent role)
+
+ # use a superuser, won't be killed
user = db.dup
- user['user'] = binding['user']
- user['password'] = binding['password']
+ user['user'] = opts[:postgresql]['user']
+ user['password'] = opts[:postgresql]['pass']
conn = connect_to_postgresql(user)
# prepare a transaction and not commit
conn.query("create table a(id int)")
conn.query("insert into a values(10)")
conn.query("begin")
conn.query("select * from a for update")
EM.add_timer(opts[:max_long_tx] * 2) {
- expect {conn.query("select * from a for update")}.should raise_error
+ expect do
+ conn.query("select * from a for update")
+ conn.query("commit")
+ end.should_not raise_error
+ conn.close if conn
+ }
+
+ # use a default user (parent role), won't be killed
+ default_user = VCAP::Services::Postgresql::Node::Provisionedservice.get(db['name']).bindusers.all(:default_user => true)[0]
+ user['user'] = default_user[:user]
+ user['password'] = default_user[:password]
+ conn = connect_to_postgresql(user)
+ # prepare a transaction and not commit
+ conn.query("create table b(id int)")
+ conn.query("insert into b values(10)")
+ conn.query("begin")
+ conn.query("select * from b for update")
+ EM.add_timer(opts[:max_long_tx] * 2) {
+ expect do
+ conn.query("select * from b for update")
+ conn.query("commit")
+ end.should_not raise_error
conn.close if conn
- EM.stop
}
+
+
+ # use a non-default user (not parent role), will be killed
+ user = db.dup
+ user['user'] = binding['user']
+ user['password'] = binding['password']
+ conn = connect_to_postgresql(user)
+ # prepare a transaction and not commit
+ conn.query("create table c(id int)")
+ conn.query("insert into c values(10)")
+ conn.query("begin")
+ conn.query("select * from c for update")
+ EM.add_timer(opts[:max_long_tx] * 2) {
+ expect {conn.query("select * from c for update")}.should raise_error
+ conn.close if conn
+ }
+ EM.stop
end
end
end

0 comments on commit f202332

Please sign in to comment.