Exemplo n.º 1
0
    def prepareServerForNewUser(self, user):
        username = ''
        if user is None:
            user = None
        elif isinstance(user, User):
            user = self.getUserCreateIfNotExistent(user.name)
        elif isinstance(user, basestring):
            user = self.getUserCreateIfNotExistent(user)
        else:
            raise ValueError('User must be either None, a User Class or a string')

        

        if self.activeUser:
            self.log.info('Logging current user out: %s' % self.activeUser.name)
            self.terminateAllComponents( self.activeUser )

        if user:
            self.log.info('Preparing the Server for new user: %s' % username)

        
        # Clear the eventHistory
        EventHistory.clear()
        
        self.activeUser = user
Exemplo n.º 2
0
	def screenReaderStopped(self, reader):
		self.log.debug( 'Screenreader stopped %s' % reader.name )
		if not self.component:
			raise AttributeError('Component is not set')
		
		if not self.isAlive():
			EventHistory.actionStopped(self, self.component)
Exemplo n.º 3
0
	def lostConnection(self):
		self.log.warning('Lost connection to %s' % str(self))
		self.log.info ('Informing all components assigned to this host')
		EventHistory.hostOffline(self)

		self.ctrlChannel = None
		self.screenReader = None
		self.ssh.disconnect()
Exemplo n.º 4
0
	def killStateChannel( self ):
		self.log.debug('Killing state channel for Action "%s"' % ( self.name ))
		if self.stateChannel:
			self.stateChannel.send(chr(3))
			self.stateChannel.send( 'exit\n' )

		if self.stateCommand:
			# non blocking commands, so only one shell required
			# kill both screens for start and stop command
			channel = self.component.host.invokeShell()
			cmd = self.createKillCmd( self.stateCommand )
			channel.send(cmd)
		self.state = None
		EventHistory.newState( self, self.component, self.state )
Exemplo n.º 5
0
	def screenReaderStopped(self, reader):
		self.log.debug( 'Action %s\'s ScreenReader stopped %s. Still alive: %s' % ( self.name, reader.name, self.isAlive() ))
		if not self.component:
			raise AttributeError('Component is not set')
		
		if not self.isAlive():
			EventHistory.actionStopped(self, self.component)

		for s in self.screenReaders['show']:
			if s.isAlive():
				self.log.debug( 'Action %s\'s Show-ScreenReader %s is alive' % ( self.name, s.name ))

		for s in self.screenReaders['hide']:
			if s.isAlive():
				self.log.debug( 'Action %s\'s Hide-ScreenReader %s is alive' % ( self.name, s.name ))
Exemplo n.º 6
0
	def start(self, globalVars=None):
		if not self.component or not self.component.host:
			raise AttributeError('Host is not set for %s' % str(self))

		if not self.isAlive():
			self.clearScreenReaders()

			if not self.canStart():
				self.log.info('Cannot start Action "%s", no commands found' % (self.name))
				return
			
			self.log.info('Starting Action "%s". "%d" Commands / "%d" dependencies found' % (self.name, len(self._startCommands), len(self.dependencies)))

			if len(self.dependencies):
				self.log.info('Action depends on: %s' % list('%s>%s' % (item.component.getName(), item.name) for item in self.dependencies))
				for dep in self.dependencies:
					dep.start()

			for cmd in self._startCommands.values():
				channel = self.component.host.invokeShell()
				command = self.createScreenCmd( cmd, globalVars )
				hideLog = cmd.hideLog
				self.startChannels.append(channel)

				screen_name = self.name + '_run'
				screenReader = ScreenReader( screen_name, channel, self.log, notifyStop=self.screenReaderStopped)
				self.screenReaders['hide' if hideLog else 'show'].append(screenReader)
				screenReader.start()

				self.log.debug('Running start command "%s" by Action "%s"' % (command.replace('\n','\\n'), self.name))
				channel.send(command)

				self.constantlyCheckState( globalVars )
				# if blocking is enabled for this command, wait for the screenreader to quit
				if cmd.blocking and screenReader and screenReader.isAlive():
					self.log.debug('Command requires blocking. Action "%s" joined the screenReader Thread. Waiting for it to finish' % self.name)
					screenReader.join( 5.0 )


			# notify EventHandler after all cmds run
			if self.isAlive():
				EventHistory.actionRun(self, self.component)
			
			return True

		else:
			self.log.debug('Could not start action "%s", Action still active' % self.name)
			return False
Exemplo n.º 7
0
	def connect(self):
		if not self.isConnected():
			try:
				self.ssh.connect()
			except socket.timeout as e:
				self.log.debug('Connection to %s timed out' % str(self))
				return False
			except Exception as e:
				self.log.debug('Could not connect to %s' % str(self))
				return False

			try:
				self.log.info('Connected to %s' % str(self))
				EventHistory.hostOnline(self)
				return True

			except Exception as e:
				self.log.exception('Could open control. Clossing %s' % str(self))
				self.screenReader = None
				self.disconnect()
				return False
Exemplo n.º 8
0
	def notifyNewStatusLine( self, screen, line ):
		configurationStart = line.rfind( '<configuration>' )
		configurationEnd = line.rfind( '</configuration' )
		if configurationStart < 0 or configurationEnd < 0:
			return
		configTxt = line[ configurationStart : configurationEnd ]

		code = ''
		codeStart = configTxt.find( '<code>' )
		codeEnd = configTxt.find( '</code>' )
		if codeStart >= 0 and codeEnd >= 0:
			code = configTxt[ codeStart+len( '<code>' ) : codeEnd ]

		message = ''
		messageStart = configTxt.find( '<message>' )
		messageEnd = configTxt.find( '</message>' )
		if messageStart >= 0 and messageEnd >= 0:
			message = configTxt[ messageStart+len( '<message>' ) : messageEnd ]

		if not self.state or self.state[ 'code' ] != code or self.state[ 'message' ] != message:
			print 'CODE: "%s", MESSGAGE: "%s"' % ( code, message )
			self.state = { 'code': code, 'message': message }
			EventHistory.newState( self, self.component, self.state )
Exemplo n.º 9
0
    def do_GET(self):
        serverThread = self.server.serverThread
        activeUser = serverThread.activeUser

        try:
            responseCode = 200
            args = {}
            options = {}
            output = None

            try:
                auth = None
                if self.headers.has_key('Authorization'):
                    userPass = None
                    auth = {'token': str(self.headers['Authorization'])}
                    if auth[ 'token' ].lower().startswith( 'basic' ):
                        # remove the leading "Basic " before splitting into user/pass
                        userPass = base64.b64decode(auth['token'][6:]).split(':')
                    elif auth[ 'token' ].lower().startswith( 'localhost' ):
                        host, port = self.client_address
                        if  host != 'localhost' and host != '127.0.0.1':
                            raise UnauthorizedRequestError( 'Only allowed by localhost', self.path )
                        name = auth[ 'token' ][ 10: ]
                        userPass = [ name, '' ]
                    else:
                        raise UnauthorizedRequestError( 'Illegal token: %s' % auth[ 'token' ], self.path) 

                    if len(userPass) != 2:
                        auth = None
                        self.server.log.warn('Invalid Authorization Header: %s', str(self.headers['Authorization']))
                    else:
                        # important: always process names in lowercase
                        auth['user'] = userPass[0].lower()
                        auth['pass'] = userPass[1]
                        if not activeUser:
                            auth['status'] = WebServer.SERVER_AVAILABLE
                        elif activeUser and activeUser.name == auth['user']:
                            auth['status'] = WebServer.SERVER_IN_CHARGE
                        else:
                            auth['status'] = WebServer.SERVER_NOT_AVAILABLE
                    
                
                # if no auth was sent, return an 401 Unauthorized
                if not auth:
                    raise UnauthorizedRequestError('No Auth-Token received', self.path)
                
                
                # get the request user
                requestUser = serverThread.getUserCreateIfNotExistent(auth['user'])
                

                # split the path by the first ?
                argsString, optionsString = self.path.split('?', 1) if self.path.find('?') > 0 else (self.path, '')

                # parse the request (remove the leading and trailing / , then split by /)
                args = argsString.strip('/').split("/")

                # parse the options string
                temp = optionsString.split('&')
                for t in temp:
                    key, value = t.split('=',1) if t.find('=') > 0 else (t, '')
                    if key:
                        value = urllib2.unquote( urllib2.unquote(value)).replace( '+', ' ' ) if value else None
                    options[key] = value
                    

                # action is the first argument
                action = args[0]
                
                # Status Command must be available even if no user is logged in
                if action == 'status':
                    output = '{"status": %d}' % auth['status']
                    
                    
                elif action == 'info':
                    output  = '[Path]<br>%s<br>' % str(self.path)
                    output += '<br>'
                    
                    output += '[Args]<br>%s<br>' % str(args)
                    output += '<br>'
                    
                    output += '[Options]<br>%s<br>' % str(options)
                    output += '<br>'

                    output += '[ActiveUser]<br>'
                    if activeUser:
                        output += 'name:%s<br>' % activeUser.name
                    else:
                        output += 'None<br>'
                    output += '<br>'
                    
                    output += '[RequestUser]<br>name:%s<br>' % requestUser.name
                    output += '<br>'

                    output += '[Components]<br>'
                    output += "<table>"
                    output += "<tr><th>Name</th><th>Active</th><th>Online ScreenReader Show</th><th>Online ScreenReader Hide</th></tr>"
                    for comp in requestUser.components():
                        ma = comp.mainAction
                        output += '<tr>'
                        output += '<td>%s</td>' % ma.name
                        output += '<td>%s</td>' % ma.isAlive()
                        output += '<td>'
                        for s in ma.screenReaders[ 'show' ]:
                            if s.isAlive():
                                output += str( s.name )
                        output += '</td><td>'
                        for s in ma.screenReaders[ 'hide' ]:
                            if s.isAlive():
                                output += str( s.name )
                        output += '</td>'
                        output += '</tr>'
                    output += '</table>'
                    output += '<br>' * 3



                    output += '[Hosts]<br>'
                    for host in serverThread.hosts.values():
                        output += '%s<br>' % str(host)
                    output += '<br>'    
                    
                    output += '[Auth]<br>'
                    if not auth:
                        output += 'None'
                    else:
                        output += 'token: %s<br>' % auth['token']
                        output += 'user: %s<br>' % auth['user']
                    output += '<br>'
                    
                    output += '[Permission]<br>'
                    output += "Bitmask:       %s<br>" % str(requestUser.getPrivileges())
                    output += "ACTION_RUN:    %s<br>" % str(requestUser.hasPrivilege(privileges.ACTION_RUN))
                    output += "ACTION_STOP:   %s<br>" % str(requestUser.hasPrivilege(privileges.ACTION_STOP))
                    output += "ACTION_STATUS: %s<br>" % str(requestUser.hasPrivilege(privileges.ACTION_STATUS))
                    output += "COMP_ADMIN:    %s<br>" % str(requestUser.hasPrivilege(privileges.COMP_ADMIN))
                    output += "HOST_ADMIN:    %s<br>" % str(requestUser.hasPrivilege(privileges.HOST_ADMIN))
                    output += "START_SERVER:  %s<br>" % str(requestUser.hasPrivilege(privileges.START_SERVER))
                    output += "PRIV_ADMIN:    %s<br>" % str(requestUser.hasPrivilege(privileges.PRIV_ADMIN))
                    


                # privileges
                elif action == 'privileges':
                    if len(args) < 2:
                        raise ArgumentRequestError('Wrong argument count for "privileges". %s found, at least 2 Required.' % str(args), self.path)
                        
                    if args[1] == 'my':
                        output = str(requestUser.getPrivileges()) 
                        
                    elif args[1] == 'all':
                        if not requestUser.hasPrivilege(privileges.PRIV_ADMIN):
                            raise UnauthorizedRequestError('Insufficient rights.', self.path)
                        allUsersPermission = serverThread.allUsersPermission();
                        output = json.dumps({'labels': privileges.dict(), 'users': allUsersPermission})
                        
                    elif args[1] == 'submit':
                        if not requestUser.hasPrivilege(privileges.PRIV_ADMIN):
                            raise UnauthorizedRequestError('Insufficient rights.', self.path)
                        serverThread.savePermissions(options)
                        output = "Ok."
                        
                    else:
                        raise ArgumentRequestError('Invalid Argument for privileges "%s". ' % str(args[1]), self.path)
                        
                        
                    
                    
                # Request host / component data
                elif action == 'data':
                    # data/(host|comp)
                    if len(args) < 2:
                        raise ArgumentRequestError('Wrong argument count for "data". %s found, at least 2 Required.' % str(args), self.path)

                    
                    if args[1] == 'host':
                        JSONObj = {}
                        
                        for host in serverThread.hosts.values():
                            JSONObj[host.id] = host.createJSONObj()
                        output = json.dumps(JSONObj)
                        
                    
                    #TODO: use json dump a la json.dump(comp.webInformation)!
                    elif args[1] == 'comp':
                        JSONObj = {}

                        for comp in requestUser.components():
                            JSONObj[comp.id] = comp.createJSONObj();
                        output = json.dumps(JSONObj)    
                        
    
                    # Events                    
                    elif args[1] == 'eventHistory':
                        # you must be in charge
                        if not auth['status'] == WebServer.SERVER_IN_CHARGE:
                            raise UnauthorizedRequestError('You are not in charge.', self.path)
                        
                        if len(args) != 3:
                            raise ArgumentRequestError('Wrong argument count for "data/eventHistory". %s found, 3 Required.' % str(args), self.path)
                        
                        if not args[2].isdigit():
                            raise ArgumentRequestError('Invalid argument for timestamp "%s". timestamp must be numerical.' % args[2], self.path)
                        
                        timestamp = int(args[2])
                        data = EventHistory.getEventData(timestamp)
                        #TODO: use json dump
                        outputObject = { "timestamp": time.time(), "events": data }
                        output = json.dumps( outputObject )
                        
                        
                    else:
                        raise ArgumentRequestError('Invalid Argument for data "%s". ' % str(args[1]), self.path)
                
                
                elif action == 'parameters':
                    # you must be in charge
                    if not auth['status'] == WebServer.SERVER_IN_CHARGE:
                        raise UnauthorizedRequestError('You are not in charge.', self.path)
                    try:
                        command = args[ 1 ]
                        compId = int( args[ 2 ])
                        actionId = int( args[ 3 ]) 
                    except ( ValueError, KeyError, IndexError ) as e:
                        raise ArgumentRequestError( 'Wrong format for parameter', self.path )
                    if command not in ( 'load', 'save' ):
                        raise ArgumentRequestError( 'Wrong command type', self.path )


                    comp = activeUser.get(compId)
                    if not comp:
                        raise ArgumentRequestError('Component with id "%d" not found' % compId, self.path)
                    action = comp.getAction(actionId)
                    if not action:
                        raise ArgumentRequestError('Action "%d" for component "%d, %s" not found.' % (actionId, compId, comp.getName()), self.path)


                    if command == 'load':
                        parameters = serverThread.loadParameters( comp, action )
                        output = parameters


                    if command == 'save':
                        try:
                            print options[ 'json' ]
                            data = json.loads( options['json'] )
                            print data
                        except KeyError, e:
                            raise ArgumentRequestError( 'Data Field missing', self.path  )
                        except ValueError, e:
                            raise ArgumentRequestError('Could not decode json Object:\n%s' % options['json'], self.path)
                        if serverThread.saveParameters( comp, action, data ):
                            output = '{"success": true}'
                        else:
                            output = '{"success": false}'