def occurDay(self, start, now, skip=1, day=6, occur=0): startDateTime = datetime.fromtimestamp(start, self.tzInstance) timeDelta = relativedelta(hours=startDateTime.hour, minutes=startDateTime.minute, seconds=startDateTime.second) log.debug('start date: %s; day: %d; occur: %d; skip: %d', str(startDateTime), day, occur, skip) # get a list of (mday, wday) tuples for current month c = calendar.Calendar(firstweekday=0) flatter = sum( c.monthdays2calendar(startDateTime.year, startDateTime.month), []) if occur == 5: flatter = reversed(flatter) tmp_occur = 0 else: tmp_occur = occur count = 0 #find Nth occurrence of week day for mday, wday in flatter: if wday == day and mday > 0: count += 1 log.debug('found wday %d, mday %d, count %d', wday, mday, count) if count == tmp_occur + 1 and mday >= startDateTime.day: log.debug('count matched, mday %d', mday) startDateTime = datetime( startDateTime.year, startDateTime.month, mday, tzinfo=self.tzInstance) + timeDelta startTimestamp = Time.awareDatetimeToTimestamp( startDateTime) # do we need to skip this day? if skip > 1: log.debug('skipping this occurrence. skip = %d', skip) return self.occurDay(startTimestamp + DAY_SECONDS, now, skip - 1, day, tmp_occur) elif startTimestamp >= now: log.debug( 'Window will start on: %s', str( datetime.fromtimestamp(startTimestamp, self.tzInstance))) return startTimestamp # couldn't find start day in current month, switching to 1st day of the next month if startDateTime.month == 12: startDateTime = datetime(startDateTime.year + 1, 1, 1, tzinfo=self.tzInstance) else: startDateTime = datetime(startDateTime.year, startDateTime.month + 1, 1, tzinfo=self.tzInstance) startDateTime += timeDelta return self.occurDay(Time.awareDatetimeToTimestamp(startDateTime), now, skip, day, occur)
def run(self, dmd, REQUEST): zem = dmd.ZenEventManager # Get values eventClass = REQUEST.get('eventClass', '/Status/Ping') severity = REQUEST.get('severity', '4') device = REQUEST.get('device', '') DeviceGroup = REQUEST.get('DeviceGroup', '/') System = REQUEST.get('System', '/') Location = REQUEST.get('Location', '/') DeviceClass = REQUEST.get('DeviceClass', '/') startDate = Time.ParseUSDate( REQUEST.get('startDate', zem.defaultAvailabilityStart())) endDate = Time.ParseUSDate( REQUEST.get('endDate', zem.defaultAvailabilityEnd())) return query(dmd, component='', eventClass=eventClass, severity=severity, device=device, DeviceGroup=DeviceGroup, System=System, Location=Location, DeviceClass=DeviceClass, startDate=startDate, endDate=endDate)
def testConvertingTime(self): stamp = 1478592000 # This is November 8, 2016 at 8:00:00 AM UTC chicago_time = Time.convertTimestampToTimeZone(stamp, "America/Chicago") self.assertEquals('2016/11/08 02:00:00', chicago_time) new_york_time = Time.convertTimestampToTimeZone(stamp, "America/New_York") self.assertEquals('2016/11/08 03:00:00', new_york_time)
def testInvalidTimeZoneGivesServerTime(self): """ Make sure we don't stack trace if a user gets an invalid timestamp set. """ stamp = time.time() current_time = Time.convertTimestampToTimeZone(stamp, "pepe", fmt="%H") server_time = Time.isoDateTime(stamp, fmt="%H") self.assertEquals(current_time, server_time)
def testConvertingTime(self): stamp = time.time() chicago_time = Time.convertTimestampToTimeZone(stamp, "America/Chicago", "%H") new_york_time = Time.convertTimestampToTimeZone( stamp, "America/New_York", "%H") if int(chicago_time) != 12: self.assertEquals(int(new_york_time), int(chicago_time) + 1)
def testConvertingTime(self): stamp = 1478592000 # This is November 8, 2016 at 8:00:00 AM UTC chicago_time = Time.convertTimestampToTimeZone(stamp, "America/Chicago") self.assertEquals('2016/11/08 02:00:00', chicago_time) new_york_time = Time.convertTimestampToTimeZone( stamp, "America/New_York") self.assertEquals('2016/11/08 03:00:00', new_york_time)
def getLocalizedTimestamp(year, month, day, hour, minutes): localizedExpectedDateTime = datetime(year, month, day, hour, minutes, tzinfo=tzInstance) return Time.awareDatetimeToTimestamp(localizedExpectedDateTime)
def getSummaryArgs(dmd, args): zem = dmd.ZenEventManager startDate = args.get('startDate', zem.defaultAvailabilityStart()) endDate = args.get('endDate', zem.defaultAvailabilityEnd()) startDate, endDate = map(Time.ParseUSDate, (startDate, endDate)) endDate = Time.getEndOfDay(endDate) startDate = min(startDate, endDate - 24 * 60 * 60 + 1) # endDate - 23:59:59 how = args.get('how', 'AVERAGE') return dict(start=startDate, end=endDate, function=how)
def run(self, dmd, REQUEST): zem = dmd.ZenEventManager # Get values component = REQUEST.get('component', '') eventClasses = REQUEST.get('eventClasses', '/Status/Ping') severity = REQUEST.get('severity', '4') device = REQUEST.get('device', '') groupName = REQUEST.get('groupName', '/') startDate = Time.ParseUSDate( REQUEST.get('startDate', zem.defaultAvailabilityStart())) endDate = Time.ParseUSDate( REQUEST.get('endDate', zem.defaultAvailabilityEnd())) r = Report(startDate, endDate, eventClasses, severity, device, component, groupName) result = r.run(dmd) return result
def cutover(self, dmd): container_tz = Time.getLocalTimezone() tzInstance = tz.gettz(container_tz) for brain in dmd.maintenanceWindowSearch(): try: m = brain.getObject() except Exception: continue m.timezone = container_tz m.tzInstance = tzInstance
def run(self, dmd, REQUEST): zem = dmd.ZenEventManager # Get values component = REQUEST.get('component', '') eventClass = REQUEST.get('eventClass', '/Status/Ping') severity = REQUEST.get('severity', '4') device = REQUEST.get('device', '') groups = REQUEST.get('groups', '/') Csystems = REQUEST.get('Csystems', '/') location = REQUEST.get('location', '/') DeviceClass = REQUEST.get('DeviceClass', '/') startDate = Time.ParseUSDate( REQUEST.get('startDate', zem.defaultAvailabilityStart())) endDate = Time.ParseUSDate( REQUEST.get('endDate', zem.defaultAvailabilityEnd())) r = CReport(startDate, endDate, eventClass, severity, device, component, groups, Csystems, location, DeviceClass) result = r.run(dmd) return result
def getAvailability(self, state, **kw): import Availability allowedFilters = ("device", "component", "eventClass", "systems", "severity", "prodState", "manager", "agent", "DeviceClass", "Location", "System", "DeviceGroup", "DevicePriority", "monitor") for name in allowedFilters: if hasattr(state, name): kw.setdefault(name, getattr(state, name)) if getattr(state, 'startDate', None) is not None: kw.setdefault('startDate', Time.ParseUSDate(state.startDate)) if getattr(state, 'endDate', None) is not None: # End date needs to be inclusive of events that occurred on that # date. So we advance to the last second of the day. kw.setdefault('endDate', Time.getEndOfDay(Time.ParseUSDate(state.endDate))) kw.setdefault( 'startDate', time.time() - 60 * 60 * 24 * self.defaultAvailabilityDays) return Availability.query(self.dmd, **kw)
def manage_changeUser(self, userid, password=None, sndpassword=None, roles=None, domains=None, REQUEST=None, **kw): """Change a zenoss users settings. """ user = self.acl_users.getUser(userid) if not user: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', 'User "%s" was not found.' % userid, priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: return if password and password != sndpassword: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', "Passwords didn't match. No change.", priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: raise ValueError("passwords don't match") if REQUEST: # TODO: Record all the non-password values. #updates = dict((k,v) for k,v in kw.items() if 'password' not in k.lower()) updates = {} if password: updates['password'] = '******' if roles: updates['roles': roles] if domains: updates['domains': domains] if password is None: password = user._getPassword() if roles is None: roles = user.roles if domains is None: domains = user.domains self.acl_users._doChangeUser(userid,password,roles,domains) ufolder = self.getUserSettings(userid) ufolder.updatePropsFromDict(kw) if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Settings Saved', Time.SaveMessage() ) audit('UI.User.Edit', username=userid, data_=updates) return self.callZenScreen(REQUEST) else: return user
def run(self, dmd, args): report = [] zem = dmd.ZenEventManager windows_class = None # Guard against people removing the /Server/Windows device class. try: windows_class = dmd.getObjByPath('Devices/Server/Windows') except KeyError: return [] for d in windows_class.getSubDevices(): if "MSExchangeIS" not in d.zDeviceTemplates: continue if not d.monitorDevice(): continue availability = d.availability() uptime = d.sysUpTime() uptime_string = "unknown" if uptime and uptime != -1: uptime = uptime / 100 uptime_string = Time.Duration(uptime) else: uptime = None r = Utils.Record( device=d.titleOrId(), deviceUrl=d.getPrimaryUrlPath(), availability=float(availability), availability_string=str(availability), uptime=uptime, uptime_string=uptime_string, ) for winservice in self.winservices: ws = getattr(d.os.winservices, winservice, None) if ws: r.values[winservice] = ws.getStatusString( '/Status/WinService') r.values[winservice+'_img'] = d.getStatusImgSrc( ws.getStatus()) report.append(r) return report
def addMonth(secs, dayOfMonthHint=0, tzInstance=tz.tzutc()): dateTime = datetime.fromtimestamp(secs, tzInstance) newYear = dateTime.year newMonth = dateTime.month + 1 if newMonth > 12: newYear += 1 newMonth = 1 lastDayOfMonth = calendar.monthrange(newYear, newMonth)[1] newDay = min(dayOfMonthHint, lastDayOfMonth) newDateTime = datetime(year=newYear, month=newMonth, day=newDay, hour=dateTime.hour, minute=dateTime.minute, second=dateTime.second, tzinfo=tzInstance) return Time.awareDatetimeToTimestamp(newDateTime)
def getAvailability(self, state, **kw): import Availability allowedFilters = ( "device", "component", "eventClass", "systems", "severity", "prodState", "manager", "agent", "DeviceClass", "Location", "System", "DeviceGroup", "DevicePriority", "monitor") for name in allowedFilters: if hasattr(state, name): kw.setdefault(name, getattr(state, name)) if getattr(state, 'startDate', None) is not None: kw.setdefault('startDate', Time.ParseUSDate(state.startDate)) if getattr(state, 'endDate', None) is not None: # End date needs to be inclusive of events that occurred on that # date. So we advance to the last second of the day. kw.setdefault('endDate', Time.getEndOfDay(Time.ParseUSDate( state.endDate))) kw.setdefault('startDate', time.time() - 60*60*24*self.defaultAvailabilityDays) return Availability.query(self.dmd, **kw)
def testConvertingTime(self): stamp = time.time() chicago_time = Time.convertTimestampToTimeZone(stamp, "America/Chicago", "%H") new_york_time = Time.convertTimestampToTimeZone(stamp, "America/New_York", "%H") if int(chicago_time) != 12: self.assertEquals(int(new_york_time), int(chicago_time) +1)
def manage_editUserSettings(self, oldpassword=None, password=None, sndpassword=None, roles=None, groups=None, domains=None, REQUEST=None, **kw): """Update user settings. """ # get the user object; return if no user user = self.acl_users.getUser(self.id) if not user: user = self.getPhysicalRoot().acl_users.getUser(self.id) if not user: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', 'User %s not found.' % self.id, priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: return # Verify existing password curuser = self.getUser().getId() if not oldpassword or not self.ZenUsers.authenticateCredentials( curuser, oldpassword): if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', 'Confirmation password is empty or invalid. Please'+ ' confirm your password for security reasons.', priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: raise ValueError("Current password is incorrect.") # update role info roleManager = self.acl_users.roleManager origRoles = filter(rolefilter, user.getRoles()) if not self.has_role('Manager') and roles and 'Manager' in roles: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', 'Only Managers can make more Managers.', priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: return if not self.has_role('Manager') and origRoles and \ 'Manager' in origRoles: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', 'Only Managers can modify other Managers.', priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: return # if there's a change, then we need to update # TODO: Record all the non-password values. #updates = dict((k,v) for k,v in kw.items() if 'password' not in k.lower()) updates = {} # update user roles if roles is None: roles = () origRolesSet = set(origRoles) rolesSet = set(roles) if rolesSet != origRolesSet and self.isManager(): # get roles to remove and then remove them removeRoles = origRolesSet - rolesSet for role in removeRoles: try: roleManager.removeRoleFromPrincipal(role, self.id) except KeyError: # User doesn't actually have that role; ignore pass # get roles to add and then add them addRoles = rolesSet - origRolesSet for role in addRoles: roleManager.assignRoleToPrincipal(role, self.id) updates['roles'] = roles # update group info if groups is None: groups = () groupManager = self.acl_users.groupManager origGroupsSet = set(groupManager.getGroupsForPrincipal(user)) groupsSet = set(groups) # if there's a change, then we need to update if groupsSet != origGroupsSet and self.isManager(): # get groups to remove and then remove them removeGroups = origGroupsSet - groupsSet for groupid in removeGroups: groupManager.removePrincipalFromGroup(user.getId(), groupid) # get groups to add and then add them addGroups = groupsSet - origGroupsSet for groupid in addGroups: try: groupManager.addPrincipalToGroup(user.getId(), groupid) except KeyError: # This can occur if the group came from an external source. pass updates['groups'] = groups # we're not managing domains right now if domains: msg = 'Zenoss does not currently manage domains for users.' raise NotImplementedError(msg) # update Zenoss user folder settings if REQUEST: kw = REQUEST.form self.manage_changeProperties(**kw) # update password info if self.id=='admin': userManager = self.getPhysicalRoot().acl_users.userManager else: userManager = self.acl_users.userManager if password: if password.find(':') >= 0: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', 'Passwords cannot contain a ":". Password not updated.', priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: raise ValueError("Passwords cannot contain a ':' ") elif password != sndpassword: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Error', 'Passwords did not match. Password not updated.', priority=messaging.WARNING ) return self.callZenScreen(REQUEST) else: raise ValueError("Passwords don't match") else: try: userManager.updateUserPassword(self.id, password) updates['password'] = '******' except KeyError: self.getPhysicalRoot().acl_users.userManager.updateUserPassword( self.id, password) if REQUEST: loggedInUser = REQUEST['AUTHENTICATED_USER'] # we only want to log out the user if it's *their* password # they've changed, not, for example, if the admin user is # changing another user's password if loggedInUser.getUserName() == self.id: self.acl_users.logout(REQUEST) # finish up if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Settings Saved', Time.SaveMessage() ) audit('UI.User.Edit', username=self.id, data_=updates) return self.callZenScreen(REQUEST) else: return user
def server_time(self): return Time.isoDateTime()
def niceStartDateTime(self): "Return start time as a string with nice sort qualities" return "%s %s" % (Time.LocalDateTime(self.start), Time.getLocalTimezone())
def getCurrentYear(self): """ This is purely for copyright on the login page. """ return Time.getYear()
def niceStartDateTime(self): "Return start time as a string with nice sort qualities" return "%s %s" % (Time.convertTimestampToTimeZone( self.start, self.timezone), self.timezone)
def defaultAvailabilityStart(self): return Time.USDate(time.time() - 60 * 60 * 24 * self.defaultAvailabilityDays)
def getTimeZone(self): """ Returns local timezone. """ return DirectResponse(data=Time.getLocalTimezone())
def niceStartDateTime(self): "Return start time as a string with nice sort qualities" return Time.LocalDateTime(self.start)
def niceStartDate(self): "Return a date in the format use by the calendar javascript" return Time.USDate(self.start)
def niceDuration(self): """Return a human readable version of the duration in days, hours, minutes""" return Time.Duration(self.duration * 60)
def manage_editMaintenanceWindow( self, startDate='', startHours='00', startMinutes='00', durationDays='0', durationHours='00', durationMinutes='00', repeat='Never', days='Sunday', occurrence='1st', startProductionState=300, stopProductionState=RETURN_TO_ORIG_PROD_STATE, enabled=True, skip=1, REQUEST=None, startDateTime=None, timezone=None): "Update the maintenance window from GUI elements" def makeInt(v, fieldName, minv=None, maxv=None, acceptBlanks=True): if acceptBlanks: if isinstance(v, str): v = v.strip() v = v or '0' try: v = int(v) if minv is not None and v < minv: raise ValueError if maxv is not None and v > maxv: raise ValueError except ValueError: if minv is None and maxv is None: msg = '%s must be an integer.' % fieldName elif minv is not None and maxv is not None: msg = '%s must be between %s and %s inclusive.' % ( fieldName, minv, maxv) elif minv is not None: msg = '%s must be at least %s' % (fieldName, minv) else: msg = '%s must be no greater than %s' % (fieldName, maxv) msgs.append(msg) v = None return v oldAuditData = self.getAuditData() prodStates = dict( (key, value) for (key, value) in self.dmd.getProdStateConversions()) msgs = [] self.enabled = bool(enabled) if not timezone: # Use container timezone timezone = time.strftime('%Z') try: tzInstance = tz.gettz(timezone) except: msgs.append("'timezone' has wrong value") if startDateTime: t = int(startDateTime) else: startHours = int(startHours) if startHours else 0 startMinutes = int(startMinutes) if startMinutes else 0 self.enabled = bool(enabled) try: month, day, year = re.split('[^ 0-9]', startDate) except ValueError: msgs.append("Date needs three number fields") day = int(day) month = int(month) year = int(year) if not msgs: startDateTime = datetime(year, month, day, startHours, startMinutes, tzinfo=tzInstance) t = Time.awareDatetimeToTimestamp(startDateTime) if repeat not in self.REPEAT: msgs.append('\'repeat\' has wrong value.') if not isinstance(enabled, bool): msgs.append('\'enabled\' has wrong value, use true or false.') if not (startProductionState in prodStates.values() or prodStates.get(startProductionState, None)): msgs.append('\'startProductionState\' has wrong value.') elif isinstance(startProductionState, str): startProductionState = prodStates[startProductionState] if not msgs: durationDays = makeInt(durationDays, 'Duration days', minv=0) durationHours = makeInt(durationHours, 'Duration hours', minv=0, maxv=23) durationMinutes = makeInt(durationMinutes, 'Duration minutes', minv=0, maxv=59) if not msgs: duration = (durationDays * (60 * 24) + durationHours * 60 + durationMinutes) if duration < 1: msgs.append('Duration must be at least 1 minute.') if msgs: if REQUEST: messaging.IMessageSender(self).sendToBrowser( 'Window Edit Failed', '\n'.join(msgs), messaging.WARNING) else: raise Exception('Window Edit Failed: ' + '\n'.join(msgs)) else: self.start = t self.duration = duration self.repeat = repeat self.days = days self.occurrence = occurrence self.startProductionState = startProductionState self.stopProductionState = stopProductionState self.skip = skip self.timezone = timezone self.tzInstance = tzInstance now = time.time() if self.started: if ((t + duration * 60) < now) or (t > now) or (not self.enabled): # We're running. If we should have already ended OR the start was # moved into the future OR the MW is now disabled, end(). self.end() elif (t < now) and ((t + duration * 60) > now) and (self.enabled): # We aren't running, but we've scheduled the MW to be going on right now. self.begin() if REQUEST: flare = 'Maintenance window changes were saved.' if self.enabled: flare += ' Next run on %s' % time.strftime( "%m/%d/%Y %H:%M:%S", time.localtime(self.next())) messaging.IMessageSender(self).sendToBrowser( 'Window Updated', flare) audit('UI.MaintenanceWindow.Edit', self, data_=self.getAuditData(), oldData_=oldAuditData) if REQUEST: return REQUEST.RESPONSE.redirect(self.getUrlForUserCommands())
def getString(self): """Date in format 2006/09/13 12:16:06.000 """ return Time.LocalDateTime(self.date.timeTime())
def defaultAvailabilityEnd(self): return Time.USDate(time.time())
def lastVersionCheckedString(self): if not self.dmd.lastVersionCheck: return "Never" return Time.LocalDateTime(self.dmd.lastVersionCheck)
def _next(self, now): if not self.enabled: return None if self.skip is None: self.skip = 1 if now is None: now = time.time() if now < self.start: return self.start if self.repeat == self.NEVER: if now > self.start: return None return self.start elif self.repeat == self.DAILY: daysSince = (now - self.start) // DAY_SECONDS dateTime = datetime.fromtimestamp( self.start, self.tzInstance) + relativedelta(days=daysSince + self.skip) return Time.awareDatetimeToTimestamp(dateTime) elif self.repeat == self.EVERY_WEEKDAY: weeksSince = (now - self.start) // WEEK_SECONDS weekdaysSince = weeksSince * 5 # start at the most recent week-even point from the start baseDateTime = datetime.fromtimestamp( self.start, self.tzInstance) + relativedelta(weeks=weeksSince) nowDateTime = datetime.fromtimestamp(now, self.tzInstance) while 1: dow = baseDateTime.weekday() if dow not in (5, 6): if baseDateTime > nowDateTime and weekdaysSince % self.skip == 0: break weekdaysSince += 1 baseDateTime += relativedelta(days=1) assert baseDateTime >= nowDateTime return Time.awareDatetimeToTimestamp(baseDateTime) elif self.repeat == self.WEEKLY: weeksSince = (now - self.start) // WEEK_SECONDS dateTime = datetime.fromtimestamp( self.start, self.tzInstance) + relativedelta(weeks=weeksSince + self.skip) return Time.awareDatetimeToTimestamp(dateTime) elif self.repeat == self.MONTHLY: months = 0 m = self.start dayOfMonthHint = datetime.fromtimestamp(self.start, self.tzInstance).day while m < now or months % self.skip: m = addMonth(m, dayOfMonthHint, self.tzInstance) months += 1 return m elif self.repeat == self.NTHWDAY: return self.occurDay(self.start, now, self.skip, self.DAYS.index(self.days), self.OCCURRENCE.index(self.occurrence)) raise ValueError('bad value for MaintenanceWindow repeat: %r' % self.repeat)
def getStringSecsResolution(self): """Date in format 2006/09/13 12:16:06 """ return Time.LocalDateTimeSecsResolution(self.date.timeTime())
def getLocalizedTimestamp(dateTime): localized_expected_time = dateTime.replace(tzinfo=tzInstance) return Time.awareDatetimeToTimestamp(localized_expected_time)
def testGetServerTimeZone(self): zone = Time.getServerTimeZone() # this one is kinda difficult since it is dependent on the host system # so lets just make sure we got something with no stack traces self.assertTrue(zone is not None, "Was unable to get the timezone from the server")